簡體   English   中英

重新定義monad列表實例

[英]Redefining monad list instance

我試圖使用newtype重新定義monad列表實例,以創建一個包裝列表類型,以便完全做到這一點,因為似乎Prelude定義無法被覆蓋。

到目前為止,我有以下內容:

newtype MyList a = MyList { unMyList :: [a] }
    deriving Show

myReturn :: a -> [a]
myReturn x = [x]

myBind ::  [a] -> (a -> [b]) -> [b]
myBind m f = concat $ map f m

instance Monad MyList where
    return x = MyList [x]
    xs >>= f = undefined

作為Haskell的初學者,我不知所措,不知道如何使用我的函數為bind定義實例的>> =運算符。

myReturn和myBind函數應該使用MyList而不是普通類型變量來具有類型嗎? 如何正確定義>> =所需的打包?

我被困在映射f的函數參數上,其中f :: a-> [b],但似乎我需要f :: a-> MyList b,但是map不會接受它作為參數。

抱歉造成混亂。 感謝所有協助。

[我知道這里有一個類似的問題: 重新定義列表monad實例,但我恐怕無法在那里找到答案。]

您只需要解開MyList類型,對其進行操作,然后將其包裝起來即可:

instance Monad MyList where
    return x = MyList [x]
    (MyList xs) >>= f = MyList . concat . map unMyList . map f $ xs

您可以(並且應該)將此壓縮MyList $ concatMap (unMyList . f) xs ,但出於說明目的,我將其擴展了。 您可以通過為MyList定義自己的mapconcat函數來簡化此定義:

myMap :: (a -> b) -> MyList a -> MyList b
myMap f (MyList xs) = MyList $ map f xs

myConcat :: MyList (MyList a) -> MyList a
myConcat (MyList xs) = MyList $ concat $ map unMyList xs

myConcatMap :: (a -> MyList b) -> MyList a -> MyList b
myConcatMap f xs = myConcat $ myMap f xs

instance Monad MyList where
    return x = MyList [x]
    xs >>= f = myConcatMap f xs

現在,它看起來像普通的列表實例:

instance Monad [] where
    return x = [x]
    xs >>= f = concatMap f xs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM