簡體   English   中英

如何測試一個應用實例的同態定律?

[英]How to test the homomorphism law of an Applicative instance?

我在做Typeclassopedia的練習; 在“ Applicative部分”中,我編寫了ZipListpure函數,並檢查它是否符合Applicative法律。

我檢查了:

  • 身份法
  • 互換法
  • 組成定律

但是,當我嘗試檢查“同態”定律時,我發現GHCi沒有獲得作為MZipList的結果。

我認為這是因為我想為我的Applicative類型類指定pure類型。 我如何運行一個pure功能,而不<*>Applicative立刻?

這是MZipList定義和類實例:

newtype MZipList a = MZipList { getZipList :: [a] }
    deriving (Show)

instance Functor MZipList where
  fmap gs x = pure gs <*> x

instance Applicative MZipList where
  pure a= MZipList (repeat a)
  (MZipList gs) <*> (MZipList xs) = MZipList (zipWith ($) gs xs)

例如,當我檢查“交換”法時:

*Main> (MZipList [(*2),(*3),(*4)]) <*> pure (2)
MZipList {getZipList = [4,6,8]}
*Main> pure ($ 2) <*> (MZipList [(*2),(*3),(*4)])
MZipList {getZipList = [4,6,8]}

但是,當我檢查“同態”定律時, MZipListpure不被調用:

*Main> pure (*2) <*> pure 2
4
*Main>  pure ((*2) 2)
4
*Main>

這是為什么?

什么是pure

pure只是將“對象”“插入”特定Applicative單子內部的函數。 例如在:

test :: [Int]
test = pure 1 -- [1]

我們將1插入到monad列表中,這將導致單例[1] 如果您已經閱讀過Monad類,那么purereturn基本相同(如果您不擔心的話)。

您的Applicative實例似乎運行良好。

您的測試

在GHCi中運行命令時,您基本上位於IO monad中,這也是一個Applicative 因此,通常, pure x返回IO (type of x)

在:

pure (*2) <*> pure 2

您要在IO對象中“放入” (*2) ,然后在IO對象中也放入2 ,最后按instance Applicative IO中的定義調​​用<*>

您沒有測試MZipList實例。

在第二個示例中,您只是調用:

pure ((*2) 2)

如果您還記得, (*2) 2只需將(*2)應用於2 ,從而真正執行2 * 2 因此,您的電話實際上是:

pure 4

在GHCi中(仍然在IO monad的上下文中)返回IO Int對象。

如何正確測試

要測試“同態”定律,您只需要向編譯器提供有關您真正想要哪種類型的小提示:

所以代替:

pure (*2) <*> pure 2

你會寫:

pure (*2) <*> (pure 2 :: MZipList Int)

現場演示

暫無
暫無

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

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