首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fmap不适用于我的数据类型列表。

fmap不适用于我的数据类型列表。
EN

Stack Overflow用户
提问于 2017-02-24 08:13:57
回答 3查看 96关注 0票数 1

我将我的数据类型定义为:

代码语言:javascript
复制
data MyMaybe a = Lust a | Lothing deriving (Show,Eq,Ord,Functor, Foldable)

当我输入fmap (+3) Lust 4时,它给了我正确的答案:Lust 7

但是,当我输入fmap (+3) [Lust 4, Lust 5]时,它不起作用,我得到了折叠错误:

代码语言:javascript
复制
Non type-variable argument in the constraint: Num (MyMaybe a)

请告诉我该做什么来解决这个错误。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-24 08:18:53

在本例中,fmap (+3)适用于单个MyMaybe。如果要将函数映射到列表上,则映射该函数。让我们给fmap (+3)取一个名字:

代码语言:javascript
复制
myMaybePlus3 :: Num a => MyMaybe a -> MyMaybe a
myMaybePlus3 = fmap (+3)

现在我们可以看到,它只适用于单个MyMaybe。我们可以使用map (或fmap)将其用于列表:

代码语言:javascript
复制
map myMaybePlus3 [Lust 4, Lust 5]

但是由于引用的透明性,我们也可以简单地写

代码语言:javascript
复制
map (fmap (+3)) [Lust 4, Lust 5]

所以你所缺少的只是一个额外的(f)map

票数 3
EN

Stack Overflow用户

发布于 2017-02-24 08:17:54

看看fmap的类型

代码语言:javascript
复制
fmap :: Functor f => (a -> b) -> f a -> f b

当你做的时候

代码语言:javascript
复制
fmap (+3) [Lust 4, List 5]

您在列表fmap上使用[],所以在本例中f aNum b => [MyMaybe b]

列表上fmap的实现是映射列表的所有元素。在本例中,元素是MyMaybe's。但是您不能将+3应用于您的MyMaybe,因为它不是Num。如果你想做的话:

代码语言:javascript
复制
fmap (fmap (+3)) [Lust 4, List 5]

这将在列表的每个元素上应用函数fmap (+3)

可以使用ghci检查简单表达式的类型,例如:

代码语言:javascript
复制
Prelude> :t fmap (+3)
fmap (+3) :: (Functor f, Num b) => f b -> f b

说明fmap (+3)的参数必须是某些Num的函子。

票数 1
EN

Stack Overflow用户

发布于 2017-02-24 08:24:39

在代码中,您正在遍历列表(使用fmap),并试图将(+3)应用于所有元素,但列表元素的类型为Num a => MyMaybe a

您需要应用fmap两次。一次用于像您一样遍历列表,另一次用于遍历列表中的每个元素,该列表同样具有Num a => MyMaybe a类型。

因此,代码必须是:

fmap (fmap (+3)) [Lust 4, Lust 5]

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42433692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档