重新定义monad实例列表 [英] Redefine list monad instance
问题描述
我想为list monad提供我自己的实例。不幸的是,下面的代码在编译时会导致重复的实例声明错误。
myReturn :: a - > [a]
myBind :: [a] - > (a - > [b]) - > [b]
实例Monad []其中
return = myReturn
(>> =)= myBind
在文档中,似乎无法在导入时隐藏实例声明,并且由于列表monad实例已在前奏中声明,所以我想我无法摆脱我认为,也许我可以至少重新绑定(>> =)
,然后再重新绑定
return
这样我就可以使用我自己的实现来使用do块,因为对于(>>>)应用程序,块应该只是语法糖。 =)
和(>>)
。
let
return = myReturn
(>> =)= myBind
in
do
item1< - list1
item2< ; - list2
return(item1,item2)
不幸的是,他们的(>> =)
从其他地方,因为e它仍然使用默认列表monad实例的(>> =)
。
有没有使我的(>> =)
和 return
列表monad实例的实现方法,或者至少一个使用它们的方法吗?
您无法定义另一个 Monad
实例列表,在某些情况下,您可以定义一种新类型来解决这个问题,但是您必须手动将所有列表函数提升为新类型才能使用它们。
<要在do-blocks中使用自己的
(>> =)
和 return
,您可以使用GHC的语言扩展: { - #LANGUAGE NoImplicitPrelude# - }
模块ListMon其中
import Prelude隐藏((>> =),return)
(>> =):: [a] - > (a - > [b]) - > [b]
xs>> = foo =
的案例xs [] - > [未定义]
[x] - > foo x ++ foo x
ys - >取10 $ concatMap foo $ take 5 ys
return :: a - > [a]
return x = [x,x,x]
someList :: [Int]
someList = do
k < - [1 .. 4 ]
h < - [2..3]
返回(k + 12 * h)
导致
$ ghci ListMon
{ - snip加载消息 - }
[ 1/1]编译ListMon(ListMon.hs,解释)
确定,加载模块:
* ListMon> someList
[25,25,25,37,37,37,26,26,26,38,38,38,27,27,27,39,39,39,28,28,28,40, 40,40]
使用 NoImplicitPrelude
,desugaring of do notation使用任何(>> =)
和 return
在范围内。
I'd like to supply my own instance for the list monad. Unfortunately, the following causes a duplicate instance declaration error when compiling.
myReturn :: a -> [a]
myBind :: [a] -> (a -> [b]) -> [b]
instance Monad [] where
return = myReturn
(>>=) = myBind
From the documentation, it seems like it's not possible to hide instance declarations when importing, and since the list monad instance is already declared in the prelude, I guess I can't get rid of the import itself either.
I figured that maybe I could at least rebind (>>=)
and return
so that I would be able to use do blocks using my own implementation since do blocks are supposedly just syntactic sugar for applications of (>>=)
and (>>)
.
let
return = myReturn
(>>=) = myBind
in
do
item1 <- list1
item2 <- list2
return (item1, item2)
Unfortunately, it seems like do blocks get their (>>=)
from somewhere else, because it's still using the (>>=)
of the default list monad instance.
Is there any way to make my implementations of (>>=)
and return
an instance of list monad, or at least a way to use them with do blocks?
You cannot define another Monad
instance for lists, in some circumstances you can define a newtype to work around that, but you'd have to manually lift all list functions to the newtype to use them.
To just use your own (>>=)
and return
in do-blocks, you can use a language extension with GHC:
{-# LANGUAGE NoImplicitPrelude #-}
module ListMon where
import Prelude hiding ((>>=), return)
(>>=) :: [a] -> (a -> [b]) -> [b]
xs >>= foo = case xs of
[] -> [undefined]
[x] -> foo x ++ foo x
ys -> take 10 $ concatMap foo $ take 5 ys
return :: a -> [a]
return x = [x,x,x]
someList :: [Int]
someList = do
k <- [1 .. 4]
h <- [2 .. 3]
return (k + 12*h)
resulting in
$ ghci ListMon
{- snip loading messages -}
[1 of 1] Compiling ListMon ( ListMon.hs, interpreted )
Ok, modules loaded:
*ListMon> someList
[25,25,25,37,37,37,26,26,26,38,38,38,27,27,27,39,39,39,28,28,28,40,40,40]
With NoImplicitPrelude
, desugaring of do-notation uses whatever (>>=)
and return
are in scope.
这篇关于重新定义monad实例列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!