我是Haskell的新手,我正在尝试制作一个函数,该函数接受一个字符串,该字符串是一个运算符,并且可能返回一个函数。这样希望我可以运行以下命令:
operationOn1 "+" 5
我希望那会返回6。 这是我的代码:
add1 :: Integer -> Integer
add1 x = x + 1
sub1 :: Integer -> Integer
sub1 x = x - 1
operationOn1 :: String -> Maybe(Integer -> Integer)
operationOn1 "+" = Just add1
operationOn1 "-" = Just sub1
operationOn1 _ = Nothing
我对此还太陌生,不知道可以从谷歌那里找到任何帮助,我可以找到的有关maye关键字的所有教程都不会进入高阶函数,因此我不确定自己在做什么错
答案 0 :(得分:7)
您不能像使用Maybe (Integer -> Integer)
类型那样立即使用Integer -> Integer
类型的东西。换句话说,此行不起作用:
λ operationOn1 "+" 5
--^^^^^^^^^^^^^^^^ This part is of type `Maybe (Integer -> Integer)`.
-- ^ Using it in this way is incorrect,
-- since it is not of type `Integer -> Integer`.
实际上,如果您阅读错误消息,它会告诉您确切的情况。 始终阅读错误消息:
error:
• Couldn't match expected type ‘Integer -> t’
with actual type ‘Maybe (Integer -> Integer)’
• The function ‘operationOn1’ is applied to two arguments,
but its type ‘String -> Maybe (Integer -> Integer)’ has only one
In the expression: operationOn1 "+" 5
In an equation for ‘it’: it = operationOn1 "+" 5
因此,我们需要处理要使用的功能周围的Maybe ...
'包装器'。
有一个专门用于处理这种情况的内置函数,即(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
,如下所示:
λ operationOn1 "+" <*> Just 5
Just 6
λ operationOn1 "-" <*> Just 4
Just 3
λ operationOn1 "what?" <*> Just 3
Nothing
如果您不知道什么是贴布函子,我强烈建议您阅读LYAH chapter on functors, applicative functors, and monoids。
答案 1 :(得分:1)
您可以介绍自己的帮助器功能
($>) :: Maybe (a -> b) -> a -> Maybe b
($>) Nothing _ = Nothing
($>) (Just f) a = Just $ f a
并使用它operationOn1 "+" $> 5