我写了代码:
is3 :: Int -> Maybe Int
is3 x = is3temp 0 x
is3temp :: Int -> Int -> Maybe Int
is3temp p x = if (abs p*p*p) < (abs x) then (is3temp (p+(signum x)) x) else (if p*p*p == x then (Just p) else Nothing)
c :: Maybe Int -> Int
c (Just x) = 2*x+1
c Nothing = 0
--fun::Int -> Int
--fun = c.is3
c1:: Int -> Int
c1 x = 2*x +1
c1 0 = 0
fun::Int -> Int
fun x = (is3 x) >>= c1
如您所见is3
接受Int并返回Maybe Int。
在fun
中,我从is3
取结果解包并尝试将其发送到c1。
并获得错误
ERROR file:1627.hs:47 - Type error in application
*** Expression : is3 x >>= c1
*** Term : c1
*** Type : Int -> Int
*** Does not match : a -> b c
这里有什么问题?
答案 0 :(得分:2)
让我们检查is3 x >>= c1
:
x :: Int
is3 :: Int -> Maybe Int
c1 :: Int -> Int
||| /???\
is3 x :: Maybe Int ||| ???????
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
(>>=) is3 x :: (Int -> Maybe b) -> Maybe b
is3 x >>= c1 :: $!%&/#?
正如您所看到的,c1
不能作为>>=
的右侧,因为它的返回类型是错误的。它必须返回某种Maybe
。可以使用return . c1
:
return . c1 :: Int -> Maybe Int
或fmap
,因为monad法律规定两者必须具有相同的效果:
fmap c1 :: Maybe Int -> Maybe Int
fmap c1 (is3 x) :: Maybe Int
但是,这也会改变fun
的类型。话虽这么说,你的函数名称相当糟糕,c1
可能是一个错字(如果fun
的类型是正确的)。您实际上可能想要使用c
:
fun :: Int -> Int
fun x = c (is3 x)
答案 1 :(得分:1)
编译的一些代码:
is3 :: Int -> Maybe Int
is3 x = is3temp 0 x
is3temp :: Int -> Int -> Maybe Int
is3temp p x = if (abs p*p*p) < (abs x) then (is3temp (p+(signum x)) x) else (if p*p*p == x then (Just p) else Nothing)
c1 :: Int -> Int
c1 0 = 0
c1 x = 2*x +1
fun :: Int -> Maybe Int
fun = (fmap c1) . is3
我将fun
的类型从Int -> Int
更改为Int -> Maybe Int
,并使用fmap
代替>>=
。
我还在c1
中翻了匹配的顺序。匹配从上到下应用,因此0
案例永远不会按照您拥有的顺序应用。