小编Fra*_*nky的帖子

Pause monad

Monads可以做许多惊人的,疯狂的事情.他们可以创建具有值叠加的变量.它们可以允许您在计算之前访问未来的数据.它们可以让您编写破坏性更新,但不是真的.然后延续monad让你打破人们的思想!通常是你自己的.;-)

但这是一个挑战:你能制作一个可以暂停的单子吗?

data Pause s x
instance Monad (Pause s)
mutate :: (s -> s) -> Pause s ()
yield :: Pause s ()
step :: s -> Pause s () -> (s, Maybe (Pause s ()))

Pause单子是一种状态的单子(因此mutate,具有明显的语义).通常情况下,像这样的monad具有某种"运行"功能,它运行计算并将您送回最终状态.但Pause它是不同的:它提供了一个step函数,它运行计算直到它调用魔法yield函数.这里计算暂停,返回给调用者足够的信息以便稍后恢复计算.

额外的awesomne​​ss:允许调用者修改step调用之间的状态.(例如,上面的类型签名应该允许这样做.)


使用案例:编写执行复杂操作的代码通常很容易,但是要将其转换为也在其操作中输出中间状态的总PITA .如果您希望用户能够在执行过程中途改变某些内容,那么事情变得非常复杂.

实施思路:

  • 显然它可以用线程,锁和IO.但我们能做得更好吗?;-)

  • 继续monad疯狂的东西?

  • 也许是某种编写器monad,yield只记录当前状态,然后我们可以step通过迭代日志中的状态来"假装" 它.(显然这排除了改变步骤之间的状态,因为我们现在并没有真正"暂停"任何东西.)

monads haskell coroutine monad-transformers free-monad

64
推荐指数
6
解决办法
5407
查看次数

是`数据PoE a =空| 对aa`一个monad?

这个问题来自于一个应用而非Monad的仿函数的例子中的答案 :它声称是

data PoE a = Empty | Pair a a deriving (Functor,Eq)
Run Code Online (Sandbox Code Playgroud)

不能有monad实例,但我没有看到:

instance Applicative PoE where
    pure x = Pair x x
    Pair f g <*> Pair x y = Pair (f x) (g y)
    _        <*> _        = Empty
instance Monad PoE where
    Empty    >>= _ = Empty
    Pair x y >>= f = case (f x, f y) of 
                       (Pair x' _,Pair _ y') -> Pair x' y'
                       _ -> Empty
Run Code Online (Sandbox Code Playgroud)

实际的原因,我相信这是一个单子是,它是同构于Maybe (Pair …

monads haskell functional-programming

14
推荐指数
4
解决办法
572
查看次数

免费monad的应用实例

在尝试找到可以逐步执行/允许线程化的haskell monad时,我发现了自由monad

data Free f a = Return a | Roll (f (Free f a))
Run Code Online (Sandbox Code Playgroud)

用它的monad实例

instance (Functor f) => Monad (Free f) where
  return = Return
  Return x    >>= f = f x
  Roll action >>= f = Roll $ fmap (>>= f) action
Run Code Online (Sandbox Code Playgroud)

和它的仿函数实例

instance (Functor f) => Functor (Free f) where
  fmap f (Return x) = Return (f x)
  fmap f (Roll   x) = Roll $ fmap (fmap f) x
Run Code Online (Sandbox Code Playgroud)

我知道每个monad都是一个带有pure = return和的应用函子(<*>) = …

haskell applicative free-monad

13
推荐指数
1
解决办法
858
查看次数

独立记忆参数

我有一个模拟很多函数的调用type F = A -> B -> C -> D,其中A.. D是具体的类型.

类型的对象A具有中等寿命.(这是codegolf的ratrace的基因组.)

最昂贵的计算来自参数A.我可以像这样容易地记忆:

f1 :: F
f1 a = let expensive = trace "expensive computation!" $ expensiveComputation a
        in \b c -> expensive
Run Code Online (Sandbox Code Playgroud)

expensive通过部分应用保留一些预处理值:

preProz :: [B -> C -> D]
preProz = [f1 [], f1 [False], f2 []]
Run Code Online (Sandbox Code Playgroud)

这些痕迹表明preProz <*> [[],[[]]] <*> [1,2]我不会重新计算这些值.

现在我发现我F的一些人也会受益于预处理B.这种预处理是独立A,事实上,这样的记忆没有任何好处

f2 a …
Run Code Online (Sandbox Code Playgroud)

haskell memoization

6
推荐指数
1
解决办法
137
查看次数

了解正确的申请

对于List,为什么right apply (*>)表现为重复并附加第二个参数n次数,n第一个参数的长度在哪里?

ghci> [1,2,3] *> [4,5]
[4,5,4,5,4,5]
Run Code Online (Sandbox Code Playgroud)

haskell applicative

4
推荐指数
1
解决办法
194
查看次数

如何让这个Haskell ADT派生出Show?

ADT是免费的monad:

data Free f r = Free (f (Free f r)) | Pure r
Run Code Online (Sandbox Code Playgroud)

我希望它能够得到它,Show以便我可以在使用它时将其打印出来.例如,如果我有以下内容:

data T next = A next | B next deriving (Show)
aa = Free $ A $ Free $ B $ Pure ()
Run Code Online (Sandbox Code Playgroud)

就像现在一样,如果我添加deriving (Show)FreeADT ,我会收到以下错误:

No instance for (Show (f (Free f r)))
      arising from the first field of ‘Free’ (type ‘f (Free f r)’)
    Possible fix:
      use a standalone 'deriving instance' declaration,
        so you can specify the …
Run Code Online (Sandbox Code Playgroud)

printing haskell show free-monad

3
推荐指数
1
解决办法
157
查看次数

编译器拒绝数据构造函数的类型签名

我正在学习哈斯克尔.当我编译代码时:

data Bintree a = Nulltree | Node (Bintree a) a (Bintree a)
Nulltree :: Bintree a
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Invalid type signature: Nulltree :: Bintree a Should be of form <variable> :: <type>
Run Code Online (Sandbox Code Playgroud)

那我该怎么做呢?我试着写:

data Bintree a = Nulltree | Node (Bintree a) a (Bintree a)
Nulltree :: a -> Bintree a
Run Code Online (Sandbox Code Playgroud)

但这会产生同样的错误.

haskell

2
推荐指数
2
解决办法
119
查看次数

Monads(Haskell)的主要目的

根据我的读数,我了解Monads主要用于:

- 通过将一个函数输出类型与另一个函数输入类型匹配来构成函数.

我认为这是一篇很好的文章:

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

它解释了Monads的盒子/包装概念.但是我不明白这些包装用的是什么?除了Composition之外,Wrapper有什么好处?

IO Monad也是一个常见的例子.

name <- getLine -- name has the type String and getLine IO String
Run Code Online (Sandbox Code Playgroud)

那么这种类型差异有什么好处呢?是错误处理吗?

monads haskell

1
推荐指数
1
解决办法
197
查看次数