重新定义monad列表实例 [英] Redefining monad list instance

查看:105
本文介绍了重新定义monad列表实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用newtype重新定义monad list实例来创建一个包装的列表类型,以便完全做到这一点,因为Prelude定义似乎无法被覆盖。



到目前为止,我有以下内容:

$ new $ MyList a = MyList {unMyList :: [ a]}
导出显示

myReturn :: a - > [a]
myReturn x = [x]

myBind :: [a] - > (a - > [b]) - > [b]
myBind mf = concat $ map fm

实例Monad MyList其中
返回x = MyList [x]
xs>> = f = undefined

作为Haskell的初学者,我不知道如何定义>> =运算符对于实例,使用我的函数来定义绑定。



myReturn和myBind函数是否使用MyList而不是普通类型变量的类型?如何正确定义>> =>正确地打包和解压缩?



我陷入函数参数来映射f,其中f :: a - > [b],但似乎我需要f :: a - > MyList b,但map不会接受它作为参数。

混淆的道歉。所有帮助表示赞赏。

[我知道这里有一个类似的问题:重新定义monad实例列表,但恐怕我不能在那里看到答案。] 解决方案

你只需要解开你的 MyList 类型,对它进行操作,然后将其包装起来:

<$ p $其中
return x = MyList [x]
(MyList xs)>> = f = MyList。 concat。映射unMyList。地图f $ xs

您可以(也应该)将此缩减为 MyList $ concatMap(unMyList。f)xs ,但为了说明的目的,我已经将其展开。您可以通过为 MyList 定义您自己的 map concat 函数来简化此定义c $ c>:

  myMap ::(a  - > b) - > MyList a  - > MyList b 
myMap f(MyList xs)= MyList $ map f xs

myConcat :: MyList(MyList a) - > MyList a
myConcat(MyList xs)= MyList $ concat $ map unMyList xs

myConcatMap ::(a - > MyList b) - > MyList a - > MyList b
myConcatMap f xs = myConcat $ myMap f xs

实例Monad MyList其中
return x = MyList [x]
xs>> = f = myConcatMap f xs

现在看起来像正常的列表实例:

  instance Monad []其中
return x = [x]
xs>> = f = concatMap f xs


I am attempting to redefine the monad list instance using newtype to create a wrapped list type, so as to allow this to be done at all, since it seems the Prelude definitions are unable to be overridden.

So far I have the following:

newtype MyList a = MyList { unMyList :: [a] }
    deriving Show

myReturn :: a -> [a]
myReturn x = [x]

myBind ::  [a] -> (a -> [b]) -> [b]
myBind m f = concat $ map f m

instance Monad MyList where
    return x = MyList [x]
    xs >>= f = undefined

As a beginner in Haskell, I am at a loss to know how to define the >>= operator for the instance, using my function for the definition of bind.

Should the myReturn and myBind functions have types using MyList rather than plain type variables? How does one do the packing and unpacking necessary to define >>= properly?

I am getting stuck on the function argument to map f, where f :: a -> [b], but it seems I need f :: a -> MyList b, but then map won't accept that as an argument.

Apologies for the confusion. All assistance appreciated.

[I am aware there is a similar question here: Redefine list monad instance but I'm afraid I cannot follow the answers there.]

解决方案

You simply need to unwrap your MyList type, operate on it, then wrap it back up:

instance Monad MyList where
    return x = MyList [x]
    (MyList xs) >>= f = MyList . concat . map unMyList . map f $ xs

You can (and should) condense this to MyList $ concatMap (unMyList . f) xs, but I've left it expanded for illustrative purposes. You could simplify this definition by defining your own map and concat functions for MyList:

myMap :: (a -> b) -> MyList a -> MyList b
myMap f (MyList xs) = MyList $ map f xs

myConcat :: MyList (MyList a) -> MyList a
myConcat (MyList xs) = MyList $ concat $ map unMyList xs

myConcatMap :: (a -> MyList b) -> MyList a -> MyList b
myConcatMap f xs = myConcat $ myMap f xs

instance Monad MyList where
    return x = MyList [x]
    xs >>= f = myConcatMap f xs

And now it looks like the normal list instance:

instance Monad [] where
    return x = [x]
    xs >>= f = concatMap f xs

这篇关于重新定义monad列表实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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