什么是Comonad,如果可以用Scala语法描述的话.我发现了scalaz库的实现,但目前还不清楚它在哪里有用.
由于状态 monad 可以分解为产品(左 - 函子)和阅读器(右 - 可表示)。
-- To form a -> (a -> k) -> k
{-# LANGUAGE MultiParamTypeClasses, TypeOperators, InstanceSigs, TypeSynonymInstances #-}
type (<-:) o i = i -> o
-- I Dont think we can have Functor & Representable for this type synonym
class Isomorphism a b where
from :: a -> b
to :: b -> a
instance Adjunction ((<-:) e) ((<-:) e) where
unit :: a -> (a -> e) -> e …Run Code Online (Sandbox Code Playgroud) {-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
import Control.Comonad
import Data.Functor.Reverse
import Data.List (unfoldr)
Run Code Online (Sandbox Code Playgroud)
首先是一些背景(哈哈).我在非空列表上有拉链.
data LZipper a = LZipper (Reverse [] a) a [a]
deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable)
mkZipper :: a -> [a] -> LZipper a
mkZipper = LZipper (Reverse [])
Run Code Online (Sandbox Code Playgroud)
你可以沿着拉链向两个方向走,但你可能会掉头.
fwd, bwd :: LZipper a -> Maybe (LZipper a)
fwd (LZipper _ _ []) = Nothing
fwd (LZipper (Reverse xs) e (y:ys)) = Just $ LZipper …Run Code Online (Sandbox Code Playgroud) 我正在努力掌握comonads的概念,在阅读了这篇博文之后,我想我对他们的工作以及他们与monad的关系有了深刻的理解.但是,我想我会深入研究这个主题,只考虑一下通用列表类型的comonad实例(你知道[a])会是什么样子,而且我已经找到了一篇我不完全知道的内容.正确.
因此,考虑到博客帖子使用的实例:
class Functor w => Comonad w where
(=>>) :: w a -> (w a -> b) -> w b
coreturn :: w a -> a
cojoin :: w a -> w (w a)
Run Code Online (Sandbox Code Playgroud)
我认为实例声明[a]看起来像这样(语法[a]可能要么不可能,要么错了,但你明白了这个想法):
instance Comonad [a] where
coreturn = head
cojoin = Data.List.subsequences --this is what I'm confused about
x =>> f = map f (cojoin x)
Run Code Online (Sandbox Code Playgroud)
在这里,我们只是找到所有subsequences列表,但只使用它powerset或其他东西是完全可行的.表单列表上有几个函数,(a -> [a])对于哪一个是正确的,它有点含糊不清.
这是否意味着[a]无法作为comonad正确地实例化,或者仅仅由用户决定 …
我需要以下类功能:
class InterleavedHomomorphic x where
interleaveHomomorphism :: (forall a . f a -> g a) -> x f -> x g
Run Code Online (Sandbox Code Playgroud)
显然,我为它发明的名称绝不是任何东西的官方术语,上面的类型不是很优雅.这是一个在某些库中有名称甚至实现的概念吗?有没有更合理的方法呢?
这个函数的目的是我有一些f注释一些数据的上下文(为了这个问题Foo,Bar它只是随机的示例数据结构):
data Foo f = One (f (Bar f)) | Product (f (Foo f)) (f (Foo f))
data Bar f = Zero | Succ (f (Bar f))
Run Code Online (Sandbox Code Playgroud)
我想以多态方式转换数据的上下文; 只知道上下文之间的同态,而不是(必然)关心数据本身.这可以通过提供instance InterleavedHomomorphic Foo和instance InterleavedHomomorphic Bar在上面的例子中完成.
输出是有效的计算.因此将它封装成monad是有意义的.但是输入是上下文敏感的计算.因此将它封装到comonad中会更有意义.
但是在Haskell中,输入和输出都封装在IOmonad中.为什么?
为什么在定义函数重复时
duplicate :: w a -> w (w a)
Run Code Online (Sandbox Code Playgroud)
对于Comonad类型类(链接),您必须修改"在上下文中"的所有元素(即更改除上下文的当前值之外的元素).为什么不在Monad中使用像返回这样的东西?
示例(拉链):
data Z a = Z [a] a [a]
Run Code Online (Sandbox Code Playgroud)
为什么我不能将副本定义为
duplicate z = Z [] z []
Run Code Online (Sandbox Code Playgroud)
我试图从Comonad规则中获得重复函数的要求,但我总是得到一个副本,它只是将元素包装成monad中的返回而不需要做任何其他操作.
一篇博文说:
复制有点难以掌握.从列表拉链中,我们必须构建列表拉链的列表拉链.这背后的意义(由每个实例必须履行的comonad法律确认)是在复制结构内部移动返回原始结构,由同一移动改变
但我不明白为什么一定是那样.该FMAP在Comonad规则始终适用于包装的元素,后来这一个元素总是"展开"与提取物,为什么还要做别的事情在重复的功能不仅仅是包装的论点其他复制?
你能指出我错过了什么吗?我觉得我在某个地方犯了一些明显的错误,但我无法自己搞清楚.
在此先感谢您的回复!
data Tree t = Empty | Node t (Tree t) (Tree t)
Run Code Online (Sandbox Code Playgroud)
我们可以创建Functor实例并使用
fmap :: (t -> a) -> Tree t -> Tree a
Run Code Online (Sandbox Code Playgroud)
但是如果不是(t - > a)我想要(树t - > a)那么我可以访问整个(节点t)而不仅仅是t
treeMap :: (Tree t -> a) -> Tree t -> Tree a
treeMap f Empty = Empty
treeMap f n@(Node _ l r) = Node (f n) (treeMap f l) (treeMap f r)
Run Code Online (Sandbox Code Playgroud)
与折叠相同
treeFold :: (Tree t -> a -> a) -> a -> Tree t -> a …Run Code Online (Sandbox Code Playgroud) 在这个答案中"Monad可以成为一个comonad吗?" 我们看到了
每个Cofree Comonad对一个Alternative functor都会产生一个Monad.
什么是双重的?是否有一类函子可以自动为它们创建一个免费的monad?
我们可以为X解决这个等式吗?
适用于monad是什么X是comonad
comonad ×10
haskell ×9
monads ×5
functor ×2
applicative ×1
foldable ×1
free-monad ×1
homomorphism ×1
io ×1
list ×1
scala ×1
scalaz ×1
zipper ×1