On Mar 31, 8:57=A0pm, Chris Smith <cdsm...@[EMAIL PROTECTED]
> wrote:
> guthrie wrote:
> > For one example I saw, =A0(in Haskell)
> > =A0 =A0 numOccurrences x =3D length . filter (=3D=3D x)
> > seems fine, but
> > =A0 numOccurrences =3D (length .) . filter . (=3D=3D)
> > worries me.
>
> > Seems to me that it wouldn't typecheck.
>
> Adding parentheses in the right place makes things a little clearer. =A0
> Here's the general idea.
>
> =A0 =A0(=3D=3D) has type: =A0 a -> (a -> Bool)
> =A0 =A0filter has type: (a -> Bool) -> ([a] -> [a])
>
> so, then, by general properties of function composition,
>
> =A0 =A0filter . (=3D=3D) has type: a -> ([a] -> [a])
>
> Now length has type: [a] -> Int, so (length .) is a section that expects
> a function from some type to [a], and gives a function from that type to
> Int by composing it with length. =A0That is,
>
> =A0 =A0(length .) has type: (b -> [a]) -> (b -> Int)
>
> By unification, this polymorphic type b is matched against [a], so
> (length .) specializes to:
>
> =A0 =A0([a] -> [a]) -> ([a] -> Int)
>
> and you apply function composition again to get
>
> =A0 =A0(length .) . filter . (=3D=3D) has type a -> ([a] -> Int)
>
> and of course the parentheses are redundant, so this is the same type as
> a -> [a] -> Int, as you expect.
>
> > I don't use Haskell (rather
> > SML), but also assume that all of the functions are curried.
>
> Correct. =A0The other thing there that I don't recall seeing in ML (it's
> been a while) is sections. =A0That is, (length .) means the same thing
as
> ((.) length), or (\x -> length . x).
>
> > to restate; if one writes:
> > =A0 =A0 =A0 h =3D g . f
>
> > How would the compiler know if this is intended to define:
> > =A0 =A0h(x,y) =3D g( f(x), y) =A0 =A0 =A0 =A0 =A0 =A0# as above
> > or
> > =A0 =A0h(x,y) =3D g( f(x,y) ) =A0 =A0 =A0 =A0 =A0 =A0# as in SML
>
> Function composition is only defined on functions of one argument, so
> with curried functions, it's always interpreted as the first statement
> above. =A0If you want the second behavior, then that's not (g . f), but
> rather ((g .) . f). =A0Or, if you want to be less tricky, it's
> \x y -> g (f x y).
>
> > Trying the example in SML:
> > - val xx =3D length o filter o op=3D;
> > stdIn:40.1-40.31 Error: operator and operand don't agree [tycon
> > mismatch]
> > =A0 operator domain: ('Z list -> int) * (('Y -> bool) -> 'Z list)
operan=
d:
> > =A0 =A0 =A0 =A0 =A0 ('Z list -> int) * (('Y -> bool) -> 'Y list -> 'Y
li=
st)
> > =A0 in expression:
> > =A0 =A0 length o filter
>
> Perhaps I'm not understanding the syntax here, but it looks like you
> didn't type the same thing. =A0In Haskell:
>
> Prelude> length . filter . (=3D=3D)
>
> <interactive>:1:9:
> =A0 =A0 Couldn't match expected type `[a]'
> =A0 =A0 =A0 =A0 =A0 =A0against inferred type `[a1] -> [a1]'
> =A0 =A0 In the second argument of `(.)', namely `filter . (=3D=3D)'
> =A0 =A0 In the expression: length . filter . (=3D=3D)
> =A0 =A0 In the definition of `it': it =3D length . filter . (=3D=3D)
>
> so that doesn't work in Haskell either. =A0You need partial application
of=
> the function composition operator on length.
Hi
Interesting discussion. With Haskell, it seems -- to an admittedly
less than knowledgeable quasi-user -- one can move in the direction of
inventing a Morse-code programming style :D
Anyway, assuming we have the definition of "numOccurences" as
numOccurences :: Eq a =3D> a -> [a] -> Int
numOccurences =3D (length .) . filter . (=3D=3D)
=2E..how do we use it to write a one-liner that maps it to a range of
chars representing the alphabet (say "['a'..'z']") to check the string
"supercalifragilisticexpialidocious" and return a list of the
occurrences of all alphabet letters? (Can/should we do it using
"map"?). How do we write a "pointfree" version of this?
--
Also, here's another function:
subElement xs f p i =3D ((filter p . map f) xs)!! i
How would this be rendered "pointfree?"
Thanks.
-- K.E.


|