在Haskell中Unsequence Monad函数 [英] Unsequence Monad function within Haskell

查看:136
本文介绍了在Haskell中Unsequence Monad函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在设计Haskell的序列函数的反函数时遇到了一些麻烦,Hoogle告诉我的函数还不存在。这是它的表现:

  ghci>序列[只有7,只有8,只有9] 
只是[7,8,9]
ghci>序列[getLine,getLine,getLine]
hey
存在
堆栈交换
[hey,there,stack exchange] :: IO [String]

我的问题是制作这样的功能:

  unsequence ::(Monad m)=> m [a]  - > [ma] 

因此,它的行为如下所示:

  ghci> unsequence(Just [7,8,9])
[只有7,只有8,只有9]
ghci>序列getLine
hey
['h','e','y'] :: [IO Char] - (这实际上会导致错误,但嘿嘿。)

我实际上并不知道这是否可能,因为我会在某个时候逃离monad,我做了一个开始,但我不知道如何为这个递归函数设置一个断点:

  unsequence m =(m >> = return。head):unsequence(m>> = return。tail)

我意识到,当 m 等于 return [] 时,我需要一个断点,但并非所有monad都有 Eq 实例,那我该怎么做?这甚至有可能吗?如果是这样,为什么?为什么不呢?请告诉我。

解决方案

确实无法创建 unsequence


  1. 您可以使用 return 安全地轻松创建单值结构$ c>。

  2. 但是,从monadic结构中删除值并不安全。例如,你不能从一个空列表中删除一个元素(即<$​​ c $ c> [a] - > a 类型的函数不安全)。 b $ b
  3. 因此,我们有一个特殊的函数(即>> = ),它可以安全地从一元结构中删除一个值(如果存在的话)并返回另一个安全的monadic结构。

因此,从一个值创建一元结构是安全的。但是,从一元结构中删除一个值是不安全的。



假设我们有一个函数 extract :: Monad m => m a - >一个可以安全的从monadic结构中删除一个值。然后我们可以执行 unsequence 如下: => m [a] - > [m a]
unsequence =地图返回。提取

但是,没有安全的方法可以从一元结构中提取值。因此 unsequence [] unsequence Nothing 将返回 undefined

然而,您可以为monadic和comonadic结构创建 unsequence 函数。 Comonad 的定义如下:

  class Functor w => Comonad w where 
extract :: w a - > a
duplicate :: w a - > w(w a)
extend ::(w a - > b) - > w a - > w b

duplicate =扩展id
扩展f = fmap f。重复的

一个结构与一元结构相反。特别是:


  1. 您可以安全地从一个comonadic结构中提取一个值。
  2. 然而,您可以从一个值安全地创建一个新的共同结构,这就是为什么重复的函数可以安全地从一个值创建一个新的共同结构。

请记住 unsequence 的定义需要 return 提取?您无法从值中安全地创建新的一维结构(即,一元结构不具有 return )。因此, unsequence 函数的定义如下:

$ $ $ $ $ $ $ $ $ unsequence :: Comonad m,Monad m)=> m [a] - > [m a]
unsequence =地图返回。提取

有趣的是 sequence 可用于简单一元结构。因此,通过直觉,你可能会认为 unsequence 可以用于简单的共同结构。但并非如此,因为您需要首先从共同结构中提取列表,然后将列表中的每个元素都放入一个monadic结构中。



通用版本的 unsequence 函数将一个共享列表结构转换为一元结构列表:

  unsequence ::(Comonad w,Monad m)=> w [a]  - > [m a] 
unsequence =地图返回。提取

另一方面,序列函数因为您只是通过链接所有monad将monadic结构列表折叠为monadic列表结构:

  sequence :: Monad m => [m a]  - > m [a] 
sequence = foldr cons(return [])
其中cons mx mxs = do
x < - mx
xs < - mxs
return $ x:xs

希望有帮助。


I'm having some real trouble designing the counterfunction of Haskell's sequence function, which Hoogle tells me doesn't yet exist. This is how it behaves:

ghci> sequence [Just 7, Just 8, Just 9]
Just [7,8,9]
ghci> sequence [getLine, getLine, getLine]
hey
there
stack exchange
["hey","there","stack exchange"] :: IO [String]

My problem is making a function like this:

unsequence :: (Monad m) => m [a] -> [m a]

So that it behaves like this:

ghci> unsequence (Just [7, 8, 9])
[Just 7, Just 8, Just 9]
ghci> sequence getLine
hey
['h','e','y'] :: [IO Char] --(This would actually cause an error, but hey-ho.)

I don't actually know if that's possible, because I'd be escaping the monad at some point, but I've made a start, though I don't know how to set a breakpoint for this recursive function:

unsequence m = (m >>= return . head) : unsequence (m >>= return . tail)

I realise that I need a breakpoint when the m here is equal to return [], but not all monads have Eq instances, so how can I do this? Is this even possible? If so, why and why not? Please tell me that.

解决方案

It is indeed not possible to create an unsequence function using monads alone. The reason is:

  1. You can safely and easily create a monadic structure from a value using return.
  2. However, it is not safe to remove a value from a monadic structure. For example you can't remove an element from an empty list (i.e. a function of the type [a] -> a is not safe).
  3. Hence we have a special function (i.e. >>=) which safely removes a value from a monadic structure (if one exists), processes it and returns another safe monadic structure.

Hence it is safe to create a monadic structure from a value. However it is not safe to remove a value from a monadic structure.

Suppose we had a function extract :: Monad m => m a -> a which could “safely” remove a value from a monadic structure. We could then implement unsequence as follows:

unsequence :: Monad m => m [a] -> [m a]
unsequence = map return . extract

However, there's no safe way to extract a value from a monadic structure. Hence unsequence [] and unsequence Nothing will return undefined.

You can however create an unsequence function for structures that are both monadic and comonadic. A Comonad is defined as follows:

class Functor w => Comonad w where
    extract   :: w a -> a
    duplicate :: w a -> w (w a)
    extend    :: (w a -> b) -> w a -> w b

    duplicate = extend id
    extend f = fmap f . duplicate

A comonadic structure is the opposite of a monadic structure. In particular:

  1. You can safely extract a value from a comonadic structure.
  2. However you can't safely create a new comonadic structure from a value, which is why the duplicate function safely creates a new comonadic structure from a value.

Remember that the definition of unsequence required both return and extract? You can't safely create a new comonadic structure from a value (i.e. comonadic structures don't have return). Hence the unsequence function is defined as follows:

unsequence :: (Comonad m, Monad m) => m [a] -> [m a]
unsequence = map return . extract

Interestingly sequence works on simply monadic structures. So via intuition you might assume that unsequence works on simply comonadic structures. However it not so because you need to first extract the list from the comonadic structure and then put each element of the list into a monadic structure.

The general version of the unsequence function converts a comonadic list structure to a list of monadic structures:

unsequence :: (Comonad w, Monad m) => w [a] -> [m a]
unsequence = map return . extract

On the other hand the sequence function works on simply monadic structures because you are just folding the list of monadic structures into a monadic list structure by chaining all the monads:

sequence :: Monad m => [m a] -> m [a]
sequence = foldr cons (return [])
    where cons mx mxs = do
        x  <- mx
        xs <- mxs
        return $ x:xs

Hope that helps.

这篇关于在Haskell中Unsequence Monad函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆