[英]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 類的共同目的是什么。 但是,我需要在這種特定情況下獲得任何建議,以增強我對處理記錄之類的方式的理解。
該x
在MyMonad x
具有如式String -> a
,而f
具有如式a -> MyMonad b
,我們因此應返回MyMonad b
(即包裝的函數String -> b)
因此,我們應該構造一個將 a s :: String
映射到 a b
的函數。 我們可以通過首先將那個s
傳遞給x
函數,然后檢索 a 類型a
值來做到這一點。 接下來,我們可以使用a
作為參數調用f
並檢索MyMonad g
。 然后,我們可以應用s
來g
。
因此,我們可以將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.