簡體   English   中英

自定義`Maybe`數據類型的派生monoid實例

[英]Derive monoid instance for custom `Maybe` data type

出於學習目的,我試圖在Monoid的typeclass實例中創建一個模擬MaybeOptional數據類型,其中

-- Data.Monoid> Prelude.mappend (Just [1,2]) (Just [3,4])
-- Just [1,2,3,4]

相反,我得到了Maybe for MonoidFirst實例的行為。

-- Data.Monoid> (First (Just [1,2])) <> (First (Just [3,4]))
-- First {getFirst = Just [1,2]}

我的數據類型和typeclass實例是:

data Optional a =
  Nada
  | Only a
  deriving (Eq, Show)

 instance Monoid a
  => Monoid (Optional a) where
mempty = Nada
mappend x mempty = x
mappend mempty (Only x) = Only x
mappend (Only x) (Only y) = Only (Prelude.mappend x y)

我的問題是

  • 為什么會這樣呢?
  • 如何獲得mappend用於Optional的行為像實例Maybe是符連接列表而不是將第一Only值?

為什么會這樣呢?

因為這就是First設計方式。 First的想法是“包裝”一個Maybe a值,並像下面這樣實現Monoid

instance Monoid (First a) where
    mempty = First Nothing
    mappend l@(First (Just _)) _ = l
    mappend _ x = x

因此,它返回包裝了值Just數據構造函數的第一個First構造函數。 當我們使用mconcat時,這可能會很有用:

Prelude Data.Monoid> mconcat [First Nothing, First (Just 0), First Nothing, First (Just 118), First (Just 999)]
First {getFirst = Just 0}

因此,我們不使用Monoid (Maybe a)實現,由First決定Monoid外觀。 SumProduct Sum發生類似的情況

如何獲得mappend用於Optional的行為像實例Maybe是符連接列表而不是將第一Only值?

您的定義中有錯誤 您可以在以下函數的開頭使用mempty

mappend x mempty = x

只是一個名為mempty的變量 因此,第一行將匹配所有內容 您應該修復它,就像您打算使用的那樣:

instance Monoid a => Monoid (Optional a) where
    mempty = Nada
    mappend x Nada = x
    mappend Nada x = x
    mappend (Only x) (Only y) = Only (Prelude.mappend x y)

暫無
暫無

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

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