繁体   English   中英

如何在 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之前MyMonadx 这只是任何 Monad 的一个关键特性——允许将一些值从一种数据类型上下文放到另一个数据类型上下文中——据我所知。 老实说,我知道 Monad 实例中[a], Maybe和其他几种永远存在的类型的bind定义。 是的,我清楚地看到 Monad 类的共同目的是什么。 但是,我需要在这种特定情况下获得任何建议,以增强我对处理记录之类的方式的理解。

xMyMonad x具有如式String -> a ,而f具有如式a -> MyMonad b ,我们因此应返回MyMonad b (即包装的函数String -> b)

因此,我们应该构造一个将 a s :: String映射到 a b的函数。 我们可以通过首先将那个s传递给x函数,然后检索 a 类型a值来做到这一点。 接下来,我们可以使用a作为参数调用f并检索MyMonad g 然后,我们可以应用sg

因此,我们可以将Monad实例实现为:

instance Monad MyMonad where
    return x = MyMonad (\a -> x)
    MyMonad x >>= f = MyMonad (\s -> let MyMonad g = f (x s) in g s)

由于您定义了一个“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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM