根据'Learn you a Haskell',列表的 <*> 的实现是:
<*>
fs <*> xs = [f x | f <- fs, x <- xs]
我错了,还是基于 >>= 的这个含糖的monadic代码?
>>=
据我所知,应该可以仅使用 fmap 来实现<*>,因为应用的是Maybe的情况 .
fmap
如何仅使用 fmap 实现列表 <*> ? (可能没有连接东西?)
顺便说一下,几页之后我看到了关于 <*> 的应用 IO 的实施问题 .
IO
这个答案是对已经给出的答案的补充,并且只关注问题的一部分:
据我所知,应该可以仅使用fmap为列表实现<*>,就像应用Maybe的情况一样 . 怎么样?
你好像是指this implementation:
实例适用可能在哪里pure = Just什么<> _ =没什么(只是f)<>某事= fmap f
好吧,是的,我们也可以为列表做到这一点 - 只使用 fmap ,模式匹配和构造函数:
instance Applicative [] where pure = [] [] <*> _ = [] (f:fs) <*> something = fmap f something ++ (fs <*> something) where [] ++ yy = ys (x:xs) ++ ys = x : (xs++ys)
不可否认,这确实需要某种连接,因为列表比Maybes更复杂 . 对于列表而言,还有其他可能的应用实例,这些实例需要的代码少于“一切都有”的行为,但这些实例与默认的monad实例不兼容(这是常见的期望) .
当然,monad符号确实简化了这一过程:
instance Monad m => Applicative m where pure = return mf <*> something = mf >>= (\f -> fmap f something) -- shorter: (`fmap` something)
...对于 Maybe 和 [] 都适用 m .
Maybe
[]
m
不,这不是基于 >>= 的含糖单子代码 . 如果是, Monad [] 实例中的definition of >>=将是循环的 .
Monad []
instance Monad [] where {-# INLINE (>>=) #-} xs >>= f = [y | x <- xs, y <- f x] ...
列表推导是 let , if 和 concatMap 的语法糖 . 来自Haskell Report:
let
if
concatMap
[e | b,Q] =如果b则[e |问]其他[][e |让decls,Q] =让[e |问][e | p < - l,Q] =设ok p = [e |问]ok _ = []在concatMap中确定l
Monad [] 实例很容易根据 concatMap 定义,但 concatMap 在GHC.List中定义(现在可能在Data.Foldable中定义) . GHC.List 和 Data.Foldable 都没有导入 GHC.Base ,因此根据 concatMap 为 GHC.Base 中的列表定义 Monad 实例是不可能的:
GHC.List
Data.Foldable
GHC.Base
Monad
instance Monad [] where (>>=) = flip concatMap -- concatMap isn't imported
根据列表理解来定义这些实例需要导入包含 concatMap 的模块以重用它来定义 >>= .
在GHC中有两个implementations of list comprehensions . 一个用 GHC.Base build 和 foldr 重写它们,类似于 Data.Foldable concatMap . 另一个实现生成递归函数来代替 concatMap as described by Wadler .
build
foldr
我见过很多情况下_adllic函数满足 Applicative 实例
Applicative
instance Applicative MyMonadThatIsAlreadyDefined where pure = return (<*>) = ap
此外, <*> 不能仅使用 fmap 来编写,至少不是一般的 . 这就是 <*> 的重点 . 尝试用 fmap 来编写 <*> ,如果你管理它,我会非常惊讶(以一种表现良好并符合适用法律的方式) . 请记住链是
Functor > Applicative > Monad
> 可以被认为是超集 . 这就是说所有仿函数的集包含所有应用程序的集合,其中包含所有monad的集合 . 如果你有一个monad,那么你拥有将它用作应用程序和仿函数所需的所有工具 . 有些类型是functorial但不适用,类型是非monadic的应用 . 我认为以这种方式定义应用实例没有问题 .
>
我错了,还是基于>> =这个含糖的monadic代码?
我不知道 >>= 是否实际上用于去糖列表理解(但请参阅Cirdec 's answer for evidence that it'不),但根据 >>= 定义 <*> 实际上是完全合法的 . 在数学术语中,每个 Monad 实例都会引发一个唯一对应的 Applicative 实例
instance Applicative F where pure = return af <*> ax = af >>= \ f -> ax >>= \ x -> return (f x)
每当 F 有一个遵纪守法的 Monad 实例时,这是一个守法的 Applicative 实例 .
F
如果您熟悉数学,那么这里有一个类比:
每inner product诱导norm;
每个规范都会导致metric;
每个指标都会产生topology .
类似地,对于每个monad结构,都存在兼容的应用结构,并且对于每个应用结构都存在兼容的 fmap ( fmap f ax = pure f <*> ax ),但反过来的含义并不成立 .
fmap f ax = pure f <*> ax
据我所知,应该可以仅使用fmap实现<*>,因为应用的是Maybe的情况 .
我不明白你的意思 . fmap 肯定不足以定义 <*> ,或者每个 Functor 都是 Applicative (好吧, Apply ) .
Functor
Apply
4 回答
这个答案是对已经给出的答案的补充,并且只关注问题的一部分:
你好像是指this implementation:
好吧,是的,我们也可以为列表做到这一点 - 只使用
fmap
,模式匹配和构造函数:不可否认,这确实需要某种连接,因为列表比Maybes更复杂 . 对于列表而言,还有其他可能的应用实例,这些实例需要的代码少于“一切都有”的行为,但这些实例与默认的monad实例不兼容(这是常见的期望) .
当然,monad符号确实简化了这一过程:
...对于
Maybe
和[]
都适用m
.不,这不是基于
>>=
的含糖单子代码 . 如果是,Monad []
实例中的definition of >>=将是循环的 .列表推导是
let
,if
和concatMap
的语法糖 . 来自Haskell Report:Monad []
实例很容易根据concatMap
定义,但concatMap
在GHC.List中定义(现在可能在Data.Foldable中定义) .GHC.List
和Data.Foldable
都没有导入GHC.Base
,因此根据concatMap
为GHC.Base
中的列表定义Monad
实例是不可能的:根据列表理解来定义这些实例需要导入包含
concatMap
的模块以重用它来定义>>=
.在GHC中有两个implementations of list comprehensions . 一个用
GHC.Base
build
和foldr
重写它们,类似于Data.Foldable
concatMap
. 另一个实现生成递归函数来代替concatMap
as described by Wadler .我见过很多情况下_adllic函数满足
Applicative
实例此外,
<*>
不能仅使用fmap
来编写,至少不是一般的 . 这就是<*>
的重点 . 尝试用fmap
来编写<*>
,如果你管理它,我会非常惊讶(以一种表现良好并符合适用法律的方式) . 请记住链是>
可以被认为是超集 . 这就是说所有仿函数的集包含所有应用程序的集合,其中包含所有monad的集合 . 如果你有一个monad,那么你拥有将它用作应用程序和仿函数所需的所有工具 . 有些类型是functorial但不适用,类型是非monadic的应用 . 我认为以这种方式定义应用实例没有问题 .我不知道
>>=
是否实际上用于去糖列表理解(但请参阅Cirdec 's answer for evidence that it'不),但根据>>=
定义<*>
实际上是完全合法的 . 在数学术语中,每个Monad
实例都会引发一个唯一对应的Applicative
实例每当
F
有一个遵纪守法的Monad
实例时,这是一个守法的Applicative
实例 .如果您熟悉数学,那么这里有一个类比:
每inner product诱导norm;
每个规范都会导致metric;
每个指标都会产生topology .
类似地,对于每个monad结构,都存在兼容的应用结构,并且对于每个应用结构都存在兼容的
fmap
(fmap f ax = pure f <*> ax
),但反过来的含义并不成立 .我不明白你的意思 .
fmap
肯定不足以定义<*>
,或者每个Functor
都是Applicative
(好吧,Apply
) .