如何声明函数(类型误解可能)

dem*_*mas 2 haskell

我需要一个功能如下:

some :: (Int, Maybe Int) -> Int
some a b
     | b == Nothing = 0
     | otherwise = a + b
Run Code Online (Sandbox Code Playgroud)

用例:

some (2,Just 1)
some (3,Nothing)
map some [(2, Just 1), (3,Nothing)]
Run Code Online (Sandbox Code Playgroud)

但我的代码引发了错误:

The equation(s) for `some' have two arguments,
but its type `(Int, Maybe Int) -> Int' has only one
Run Code Online (Sandbox Code Playgroud)

我不明白.

提前致谢.

luq*_*qui 10

当你写作

foo x y = ...
Run Code Online (Sandbox Code Playgroud)

这是一个curried函数的表示法,类似于:

foo :: a -> b -> c
Run Code Online (Sandbox Code Playgroud)

你已声明你的函数期望一个元组,所以你必须写它:

some :: (Int, Maybe Int) -> Int
some (x, y) = ...
Run Code Online (Sandbox Code Playgroud)

但是,哈斯克尔惯例通常是采用以前的咖喱形式来论证.看到函数以元组为参数是非常罕见的.

对于问题的其他部分,您可能希望使用模式匹配来表达它.你可以说:

foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x + 1
Run Code Online (Sandbox Code Playgroud)

对OP的问题进行概括是为读者留下的练习.

  • @John,你认为对那些没有掌握currying和模式匹配的人建议使用Functors和无点样式是有帮助的吗? (2认同)

gsp*_*spr 7

您的错误不是来自对以下内容的误解Maybe:类型签名some表示它需要一对(Int, Maybe Int),而在您的定义中,您提供了两个参数.因此,定义应首先some (a,b)匹配类型签名.

解决问题的一种方法(也更习惯并使用模式匹配)是:

some :: (Int, Maybe Int) -> Int
some (a, Nothing) = a
some (a, Just b) = a + b
Run Code Online (Sandbox Code Playgroud)

值得注意的是,除非你有一个很好的理由使用元组作为输入,否则你可能不会这样做.如果你的签名是不是some :: Int -> Maybe Int -> Int,你有两个参数的函数,它可以令行禁止.那你就写了类似的东西

some :: Int -> Maybe Int -> Int
some a Nothing = a
some a (Just b) = a + b
Run Code Online (Sandbox Code Playgroud)

此外,您可能希望添加以下直接概括:所有Num类型都是附加的,因此您也可以这样做

some :: (Num n) => n -> Maybe n -> n
some a Nothing = a
some a (Just b) = a + b
Run Code Online (Sandbox Code Playgroud)

(我违反了使用a,b,c ...类型变量的常见做法,以免混淆OP,因为他绑定ab参数some).