質問

I've started to wrap my head around it, and rather like using it for simple situations in which I can essentially pipe the values from one output to one input. A simple example of a pointfree composition I'm comfortable with would be:

let joinLines = foldr (++) "" . intersperse "\n"

While playing with GHCI today, I wanted to see if I could compose not and (==) to replicate (/=), but I wasn't really able to reason it out. (==) take two inputs, and not takes one. I thought that this might work:

let ne = not . (==)

With the assumption that the single Bool output of (==) would go to not, but it won't compile, citing the following error:

<interactive>:1:16:
    Couldn't match expected type `Bool' with actual type `a0 -> Bool'
    Expected type: a0 -> Bool
      Actual type: a0 -> a0 -> Bool
    In the second argument of `(.)', namely `(==)'
    In the expression: not . (==)

I wish I could say it meant much to me, but all I'm getting is that maybe the second argument that's passed to (==) is mucking things up for not? Can anybody help me understand a little better the logic behind this composition?

役に立ちましたか?

解決

If you start to remove one argument at the time, you get

ne x y = not (x == y)
       = (not . (x ==)) y
ne x   = not . (x ==)
       = not . ((==) x)
       = ((not .) . (==)) x
ne     = (not .) . (==)

basically, for every argument you need one (.), properly associated.

The type of (==) is Eq a => a -> a -> Bool. So if you write whatever . (==), and pass a value x to that, you get whatever ((==) x), but (==) x is a function a -> Bool (where a is the type of x, and an instance of Eq). So the whatever must accept arguments of function type.

他のヒント

Another useful operator is (.:), which is a combinator for an initial function taking two arguments:

f . g  $ x
f .: g $ x y

Explicit use of curry and uncurry can help switch between "multi-argument" and single-argument functions.

ne = curry (not . uncurry (==))

uncurry "fixes" (==) so that it takes a single argument (x,y) rather than separate x and y arguments. The resulting function can then be composed with not as expected. The composed function, then can be re-curried to accept separate arguments again.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top