List <*&燃气轮机;对于按do符号实现的列表-isn';“这是什么?”;欺骗;?
根据“学习Haskell”,列表的List <*&燃气轮机;对于按do符号实现的列表-isn';“这是什么?”;欺骗;?,list,haskell,applicative,List,Haskell,Applicative,根据“学习Haskell”,列表的实现如下: fs <*> xs = [f x | f <- fs, x <- xs] fsxs=[fx | f= 据我所知,应该可以只使用fmap实现,因为applicative可能就是这样 仅使用fmap如何实现列表的 顺便说一句,几页之后,我看到了关于applicativeIO的实现的相同问题。我已经看到,在很多情况下,applicative实例通过一元函数得到了满足 instance Applicative MyMonadThat
实现如下:
fs <*> xs = [f x | f <- fs, x <- xs]
fsxs=[fx | f=
据我所知,应该可以只使用fmap
实现,因为applicative可能就是这样
仅使用fmap
如何实现列表的
顺便说一句,几页之后,我看到了关于applicative
IO
的
实现的相同问题。我已经看到,在很多情况下,applicative
实例通过一元函数得到了满足
instance Applicative MyMonadThatIsAlreadyDefined where
pure = return
(<*>) = ap
其中
>
可以看作是超集。这意味着所有函子的集合包含所有应用程序的集合,其中包含所有单体的集合。如果你有一个单体,那么你就有了将它用作应用程序和函子所需的所有工具。有一些类型是函数的,但不适用于应用程序,而类型是至少,应用程序不是一元的。我认为以这种方式定义应用程序实例没有问题。不,这不是基于>=
的糖化一元代码。如果是,则Monad[]
实例中的是循环的
instance Monad [] where
{-# INLINE (>>=) #-}
xs >>= f = [y | x <- xs, y <- f x]
...
Monad[]
实例很容易用concatMap
定义,但是concatMap
是在中定义的(现在可能是在中定义的)。既不是GHC.List
也不是Data.Foldable
被导入到GHC.Base
,因此不可能根据concatMap
为GHC.Base
中的列表定义Monad
实例:
instance Monad [] where
(>>=) = flip concatMap -- concatMap isn't imported
根据列表理解定义这些实例可以避免需要导入包含concatMap
的模块来重用它定义>=
在GHC中有两种。一种是根据GHC.Base
build
和foldr
重写它们,类似于Data.Foldable
concatMap
。另一种实现生成递归函数代替concatMap
是我弄错了,还是这个糖化的一元代码基于>>=
我不知道>>=
是否真的被用来消除糖类列表的理解(但请参阅Cirdec的答案,以获得证据证明它不是),但实际上,用>=
来定义
是完全合法的。用数学术语来说,每个单子
实例都会产生一个唯一的对应应用
实例,从这个意义上说
instance Applicative F where
pure = return
af <*> ax = af >>= \ f -> ax >>= \ x -> return (f x)
实例应用程序F,其中
纯=返回
af ax=af>>=\f->ax>=\x->返回(f x)
只要F
有一个守法的Monad
实例,它就是一个守法的Applicative
实例
如果你熟悉数学,这里有一个类比:
- 每一个都会导致一个错误
- 每一个规范都会导致一个错误
- 每一个度量都会产生一个度量
fmap
(fmap f ax=pure f ax
),但相反的含义并不成立
据我所知,应该可以只使用fmap来实现,因为applicative可能就是这样
我不明白你在这里的意思。fmap
当然不足以定义
,否则每个函子都将是应用的
(嗯,应用的
)。这个答案是对已经给出的答案的补充,只关注问题的一部分:
据我所知,仅使用fmap
就可以实现列表的
,因为applicative可能就是这种情况。如何实现
你似乎提到:
诚然,这确实需要某种连接,因为列表的类型比Maybes更复杂。对于列表,还有其他可能的应用实例,它们需要的代码比这种“万事通”行为少,但它们与默认monad实例(这是常见的期望)不兼容
当然,单子符号确实大大简化了这一点:
instance Monad m => Applicative m where
pure = return
mf <*> something = mf >>= (\f -> fmap f something) -- shorter: (`fmap` something)
instance Monad m=>Applicative m其中
纯=返回
mf something=mf>>=(\f->fmap f something)--较短:(`fmap`something)
…它既适用于可能也适用于和[]
asm
非常有趣!你知道@Muzietto这个我认为是如何被特别用于列表理解的吗?即编译器magic@Muzietto列表理解是let
、if
和concatMap
的语法糖,在Monad
和Appli>中不存在concatMap
cative
实例在GHC.Base
中定义;我在回答中添加了对这两个实例的解释。@BartekBanachewicz Monad理解仅在(7.3.11)中使用在GHC.Base
中启用了,但没有启用。不需要任何编译器魔法,@dfeuer我添加了一个关于列表理解是如何实际实现的注释。我被Maybe案例愚弄了,但我显然仍然需要很好地理解这些概念。你的答案很值得思考。顺便说一句,你为什么提到“应用”?我知道“白痴”ms',但不知道applicative functor的另一个名称。@Muzietto:我现在找不到它,但我在某处看到了一个Apply
类的定义,该类使用
方法,但没有单位,我相信这对涉及镜头的某些情况很有用。applicative
是unit
+
,因此仅定义
不足以使您的键入成为一个实用的@user3577858:我的意思是纯粹的。太多了
instance Applicative F where
pure = return
af <*> ax = af >>= \ f -> ax >>= \ x -> return (f x)
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
instance Applicative [] where
pure = []
[] <*> _ = []
(f:fs) <*> something = fmap f something ++ (fs <*> something)
where
[] ++ yy = ys
(x:xs) ++ ys = x : (xs++ys)
instance Monad m => Applicative m where
pure = return
mf <*> something = mf >>= (\f -> fmap f something) -- shorter: (`fmap` something)