給定以下資料型別
data Both a b = Both { left :: a, right :: b }
我可以像這樣為 Applicative 等撰寫實體(在這里省略 Functor,因為我們可以使用DeriveFunctor):
instance Monoid a => Applicative (Both a) where
pure x = Both mempty x
Both u f <*> Both v x = Both (u <> v) (f x)
由于Both與 同構(a,b),我想知道是否可以使用DerivingVia來派生實體:
data Both a b = ... deriving Applicative via ((,) a)
這會導致錯誤訊息,例如:
? Couldn't match representation of type ‘(a, a1)’
with that of ‘Both a a1’
arising from the coercion of the method ‘pure’
from type ‘forall a1. a1 -> (a, a1)’
to type ‘forall a1. a1 -> Both a a1’
? When deriving the instance for (Applicative (Both a))
我將其解釋為“編譯器不知道如何Both變成(,)”。我如何告訴編譯器使用明顯的方式來做到這一點?
我已經看到了這個問題和答案,但我希望有一個需要更少樣板的解決方案。
uj5u.com熱心網友回復:
受到這個答案的啟發,并在包的幫助下generic-data可以寫:
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
import GHC.Generics
import Generic.Data
data Both a b = Both {left :: a, right :: b}
deriving stock (Generic1)
deriving (Functor, Applicative) via Generically1 (Both a)
uj5u.com熱心網友回復:
DerivingVia論文有一節是關于使用Generic為“同構通過”的事物派生任意類的Generic。見 4.3。
我覺得我已經看到了適用于 hackage 庫的方法,但我現在似乎找不到它。
但是,我不確定它是否適用于您的情況,因為(a, b)您的型別可能沒有相同的Generic表示形式(您的型別有記錄欄位)。“資料型別通用手術”在這種情況下也可能有用 - https://github.com/Lysxia/generic-data-surgery#readme
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/434064.html
上一篇:listmonad不是一個免費的monad,但是……
下一篇:如何撰寫自由單子
