我需要一个功能如下:
some :: (Int, Maybe Int) -> Int
some a b
| b == Nothing = 0
| otherwise = a + b
用例:
some (2,Just 1)
some (3,Nothing)
map some [(2, Just 1), (3,Nothing)]
但是我的代码引发了错误:
The equation(s) for `some' have two arguments,
but its type `(Int, Maybe Int) -> Int' has only one
我不明白。
提前致谢。
答案 0 :(得分:10)
写作时
foo x y = ...
这是 curried 函数的表示法,其类型如下:
foo :: a -> b -> c
您已声明您的函数需要一个元组,因此您必须编写它:
some :: (Int, Maybe Int) -> Int
some (x, y) = ...
但是Haskell惯例通常是采用以前的咖喱形式来论证。看到函数将元组作为参数非常罕见。
对于问题的其他部分,您可能希望使用模式匹配来表达它。你可以说:
foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x + 1
对OP的问题进行概括是留给读者的练习。
答案 1 :(得分:7)
您的错误不是来自对Maybe
的误解:some
的类型签名表示它需要一对(Int, Maybe Int)
,而在您的定义中,您提供了两个参数。因此,定义应以some (a,b)
开头,以匹配类型签名。
解决问题的一种方法(也有点习惯并使用模式匹配)是:
some :: (Int, Maybe Int) -> Int
some (a, Nothing) = a
some (a, Just b) = a + b
值得注意的是,除非你有一个很好的理由使用元组作为输入,否则你可能不会这样做。如果您的签名是some :: Int -> Maybe Int -> Int
,则您将拥有两个参数的函数,可以是curried。然后你会写一些类似
some :: Int -> Maybe Int -> Int
some a Nothing = a
some a (Just b) = a + b
此外,您可能希望添加以下即时概括:所有Num
类型都是附加的,因此您也可以这样做
some :: (Num n) => n -> Maybe n -> n
some a Nothing = a
some a (Just b) = a + b
(我违反了使用a,b,c ...类型变量的常见做法,以免混淆OP,因为他将a
和b
绑定到{的参数{1}})。