如何在 Haskell 中为具有记录语法的类型定义 `bind`?
How to define `bind` for a type with record syntax in Haskell?
我在解决 Haskell 课程中的 Monad 作业时完全卡住了。有一个示例数据类型,我想为其定义特定于 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
一旦声明了 Functor 和 Applicative 实例,我就尝试为 Monad 做同样的事情,但是......我一点也不了解如何将记录语法 func
放入其中f
函数。到目前为止,我将 bind
视为在将其映射到 f
之前获取 MyMonad
的 x
的函数。据我所知,这只是任何 Monad 的一个关键特性——能够将一些值从一种数据类型上下文放入另一种数据类型上下文。老实说,我知道 Monad 实例中 [a], Maybe
的 bind
定义和其他几种永远存在的类型。是的,我清楚地看到 Monad class 服务的共同目的是什么。但是,我需要在这个特定案例中得到任何建议,只是为了增强我对处理记录之类的方式的理解。
MyMonad x
中的x
的类型为String -> a
,而f
的类型为a -> MyMonad b
,因此我们应该return一个MyMonad b
(包装函数 String -> b)
.
因此,我们应该构建一个将 s :: String
映射到 b
的函数。我们可以先将 s
传递给 x
函数,然后检索类型为 a
的值。接下来我们可以使用 a
作为参数调用 f
,然后检索 MyMonad g
。然后我们可以将 s
应用到 g
.
因此我们可以将 Monad
实例实现为:
instance Monad MyMonad where
return x = MyMonad (\a -> x)
MyMonad x >>= f = MyMonad (<b>\s -> let MyMonad g = f (x s) in g s</b>)
因为你定义了一个 "getter" func :: MyMonad a -> a -> String
,我们可以使用 getter 而不是使用 let … in …
表达式来 "unwrap" 输出值MyMonad
数据构造函数的:
instance Monad MyMonad where
return x = MyMonad (\a -> x)
MyMonad x >>= f = MyMonad (<b>\s -> func (f (x s)) s</b>)
我在解决 Haskell 课程中的 Monad 作业时完全卡住了。有一个示例数据类型,我想为其定义特定于 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
一旦声明了 Functor 和 Applicative 实例,我就尝试为 Monad 做同样的事情,但是......我一点也不了解如何将记录语法 func
放入其中f
函数。到目前为止,我将 bind
视为在将其映射到 f
之前获取 MyMonad
的 x
的函数。据我所知,这只是任何 Monad 的一个关键特性——能够将一些值从一种数据类型上下文放入另一种数据类型上下文。老实说,我知道 Monad 实例中 [a], Maybe
的 bind
定义和其他几种永远存在的类型。是的,我清楚地看到 Monad class 服务的共同目的是什么。但是,我需要在这个特定案例中得到任何建议,只是为了增强我对处理记录之类的方式的理解。
MyMonad x
中的x
的类型为String -> a
,而f
的类型为a -> MyMonad b
,因此我们应该return一个MyMonad b
(包装函数 String -> b)
.
因此,我们应该构建一个将 s :: String
映射到 b
的函数。我们可以先将 s
传递给 x
函数,然后检索类型为 a
的值。接下来我们可以使用 a
作为参数调用 f
,然后检索 MyMonad g
。然后我们可以将 s
应用到 g
.
因此我们可以将 Monad
实例实现为:
instance Monad MyMonad where
return x = MyMonad (\a -> x)
MyMonad x >>= f = MyMonad (<b>\s -> let MyMonad g = f (x s) in g s</b>)
因为你定义了一个 "getter" func :: MyMonad a -> a -> String
,我们可以使用 getter 而不是使用 let … in …
表达式来 "unwrap" 输出值MyMonad
数据构造函数的:
instance Monad MyMonad where
return x = MyMonad (\a -> x)
MyMonad x >>= f = MyMonad (<b>\s -> func (f (x s)) s</b>)