簡體   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