[英]How to define `bind` for a type with record syntax in Haskell?
I'm completely stuck when solving a Monad assignment in Haskell course.在 Haskell 课程中解决 Monad 作业时,我完全陷入困境。 There is a sample data type I want to define Monad-specific functions for:
有一个示例数据类型,我想为以下对象定义 Monad 特定的函数:
data MyMonad a = MyMonad { func :: String -> a }
instance Functor MyMonad where
fmap f (MyMonad x) = MyMonad (\a -> f (x a))
instance Applicative MyMonad where
pure x = MyMonad (\a -> x)
(MyMonad f) <*> (MyMonad g) = MyMonad (\a -> (f a)(g a))
instance Monad MyMonad where
return x = MyMonad (\a -> x)
MyMonad x >>= f = f (\a -> x a) --my wrong definition
Once Functor and Applicative instances declared, I'm trying to do the same for Monad, but...I'm not a little bit closer to understand how to fit a record syntax func
into that f
function.一旦声明了 Functor 和 Applicative 实例,我就会尝试为 Monad 做同样的事情,但是......我并没有更深入地了解如何将记录语法
func
放入该f
函数中。 So far I see bind
as a function to take an x
of MyMonad
before mapping it over f
.到目前为止,我认为
bind
是一个函数,在将它映射到f
之前MyMonad
的x
。 It's just a cricial feature of any Monad - enable putting some values from one data type context to another one - as far as I realize that.这只是任何 Monad 的一个关键特性——允许将一些值从一种数据类型上下文放到另一个数据类型上下文中——据我所知。 To be honest, I'm aware of
bind
definitions in Monad instances for [a], Maybe
and several other everpresent types.老实说,我知道 Monad 实例中
[a], Maybe
和其他几种永远存在的类型的bind
定义。 Yes, I see clearly what's a common purpose the Monad class serves for.是的,我清楚地看到 Monad 类的共同目的是什么。 However, I need to get any suggestion in this specific case just to enhance my understanding about the way to deal with something like records.
但是,我需要在这种特定情况下获得任何建议,以增强我对处理记录之类的方式的理解。
The x
in MyMonad x
has as type String -> a
, whereas f
has as type a -> MyMonad b
, we thus should return a MyMonad b
(that wraps a function String -> b)
.该
x
在MyMonad x
具有如式String -> a
,而f
具有如式a -> MyMonad b
,我们因此应返回MyMonad b
(即包装的函数String -> b)
We thus should construct a function that maps a s :: String
to a b
.因此,我们应该构造一个将 a
s :: String
映射到 a b
的函数。 We can do that by first passing that s
to the x
function, and retrieve a value of type a
.我们可以通过首先将那个
s
传递给x
函数,然后检索 a 类型a
值来做到这一点。 Next we can call f
with a
as that parameter, ands retrieve a MyMonad g
.接下来,我们可以使用
a
作为参数调用f
并检索MyMonad g
。 We can then apply that s
to g
.然后,我们可以应用
s
来g
。
We can thus implement the Monad
instance as:因此,我们可以将
Monad
实例实现为:
instance Monad MyMonad where
return x = MyMonad (\a -> x)
MyMonad x >>= f = MyMonad (
\s -> let MyMonad g = f (x s) in g s)
since you defined a "getter" func :: MyMonad a -> a -> String
, we can make use of that getter instead of using a let … in …
expression to "unwrap" the value out of the MyMonad
data constructor:由于您定义了一个“getter”
func :: MyMonad a -> a -> String
,我们可以使用该 getter 而不是使用let … in …
表达式来“解包” MyMonad
数据构造函数中的值:
instance Monad MyMonad where
return x = MyMonad (\a -> x)
MyMonad x >>= f = MyMonad (
\s -> func (f (x s)) s)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.