当我有两个功能时:
A)
three :: Int -> Maybe Int
three a
| a == 3 = Just 3
| otherwise = Nothing
b)中
takeOne :: Int -> Int
takeOne a = (a - 1)
如何将函数a作为函数b的参数调用?即我如何让功能b接受一个可能的Int'代替' Int'?
在我尝试的那一刻
takeOne (three 3)
我收到错误:
ERROR - Type error in application
*** Expression : takeThree (three 3)
*** Term : three 3
*** Type : Maybe Int
*** Does not match : Int
感谢。
答案 0 :(得分:14)
您有一些选择,但我说最简单的是fmap
:
fmap :: Functor f => (a -> b) -> f a -> f b
示例:
> fmap takeOne $ three 3
Just 2
> fmap takeOne $ three 2
Nothing
另一种选择是使用函数maybe
,该函数采用默认值,函数应用于Just
内的任何值,然后使用Maybe a
将其应用于。一个例子应该清楚
> maybe 0 takeOne $ three 3
2
> maybe 0 takeOne $ three 2
0
如果您只想提供默认值,另一种选择是使用fromMaybe
中的Data.Maybe
函数:
> import Data.Maybe
> fromMaybe 0 $ three 3
3
> fromMaybe 0 $ three 2
0
在Haskell中,有一个名为Functor
的类型类定义为
class Functor f where
fmap :: (a -> b) -> f a -> f b
有许多类型是Functor
的实例。实际上,所有参数化数据结构都是Functor
s,所有Applicative
和Monad
都是Functor
s。 fmap = map
最简单的心智模型是它只是一个容器的奇特名称。例如,对于列表> fmap (+1) (Left "error")
Left "error"
> fmap (+1) (Right 1)
Right 2
> x <- fmap (++", world") getLine
Hello
> x
Hello, world
> fmap (+1) [1..5]
[2,3,4,5,6]
> fmap (+1) ("fst", 2)
("fst", 3)
。它只是将一个函数映射到容器内的元素。
还有一些例子:
Functor
甚至函数都是fmap = (.)
s!这里> let lengthPlusOne = fmap (+1) length
> lengthPlusOne "Hello"
6
,它只是正常的功能组成:
{{1}}
答案 1 :(得分:0)
另一种选择当然是自己编写。
data IAcceptedAMaybeInt = GotAnswer Int | NothingAtTheMoment deriving Show
pleaseAcceptAMaybeInt f g a = case g a of
Just b -> GotAnswer (f b)
otherwise -> NothingAtTheMoment
输出:
*Main> pleaseAcceptAMaybeInt takeOne three 3
GotAnswer 2
*Main> pleaseAcceptAMaybeInt takeOne three 2
NothingAtTheMoment