[英]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
定義自己的map
和concat
函數來簡化此定義:
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.