I am new to Haskell, using Ghci.
I have a function, called three, that I want to write as
let three = \x->(\y->(x(x(x y))))
OK, this works, but when I try 开发者_如何转开发
three (2+) 4
It does not work. Instead, I get some "cannot construct infinite type" error.
Please help me.
ghci> let three = \x->(\y->(x(x(x y))))
ghci> three (2+) 4
10
ghci> three return "deconstructivist"
<interactive>:1:6:
Occurs check: cannot construct the infinite type: t = m t
Expected type: t
Inferred type: m t
In the first argument of 'three', namely 'return'
In the expression: three return "deconstructivist"
ghci> :t three
three :: (t -> t) -> t -> t
ghci> :t return
return :: (Monad m) => a -> m a
- The example you supplied of
three (2+) 4
, works! Better check that the examples you provide actually reproduce your problem. - As for with a different example, like the one above with
return
, the thing is that return results in a different type than the one given. If the type was the same, it would be infinite (and of kind* -> * -> * -> ...
), which Haskell does not support.
The example you give does work. Let's explain why:
three f = f . f . f
-- so...
three :: (a -> a) -> a -> a
The function needs to have type a -> a
because it will receive it's own argument, which requires a type. (2+)
has type Num a => a -> a
, so three (2+) 4
will work just fine.
However, when you pass a function like return
of type Monad m => a -> m a
, which returns a different type, it will not match the (a -> a)
requirement we set out. This is where and when your function will fail.
While you're at it, try making a function like doTimes
with type Integer -> (a -> a) -> a -> a
which does the given function the given number of times - it's a good next step after making this function.
精彩评论