在Maybe列表上操作

Joh*_*Doe 2 haskell functor maybe

我可以每2乘以一个列表:

(* 2) <$> [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

但我想要乘以Just的元素:

(* 2) <$> [Just 1, Nothing, Just 3]
Run Code Online (Sandbox Code Playgroud)

错误:

* Non type-variable argument in the constraint: Num (Maybe a)
  (Use FlexibleContexts to permit this)
* When checking the inferred type
    it :: forall a. (Num (Maybe a), Num a) => [Maybe a] Prelude Data.List 
Run Code Online (Sandbox Code Playgroud)

另一个尝试:

fmap (* 2) [Just 1, Nothing, Just 3]
Run Code Online (Sandbox Code Playgroud)

错误:

* Non type-variable argument in the constraint: Num (Maybe a)
  (Use FlexibleContexts to permit this)
* When checking the inferred type
    it :: forall a. (Num (Maybe a), Num a) => [Maybe a]
Run Code Online (Sandbox Code Playgroud)

我尝试了更多的东西:map2,fmap2,map(*2)map等.

dup*_*ode 9

一个简单的解决方案是添加另一个fmap来通过该Maybe层:

GHCi> fmap (* 2) <$> [Just 1, Nothing, Just 3]
[Just 2,Nothing,Just 6]
Run Code Online (Sandbox Code Playgroud)

或者,可以使用表示Compose,这允许将两个仿函数层处理为一个:

GHCi> import Data.Functor.Compose
GHCi> (* 2) <$> Compose [Just 1, Nothing, Just 3]
Compose [Just 2,Nothing,Just 6]
GHCi> getCompose $ (* 2) <$> Compose [Just 1, Nothing, Just 3]
[Just 2,Nothing,Just 6]
Run Code Online (Sandbox Code Playgroud)


Fyo*_*kin 6

你需要映射两次:一次进入列表,第二次进入可能.操作员<$>只映射一次,并且您不能使用相同的运算符两次,因此您必须添加一个调用fmap:

fmap (* 2) <$> [Just 1, Nothing, Just 3]
Run Code Online (Sandbox Code Playgroud)

  • 当然可以,语法是`((*2)<$>)<$> [Just 1,Nothing,Just 3]`.只有你喜欢被故意插入才能做到这一点. (2认同)