考慮這種型別:
data Vec3 = Vec3 {_x, _y, _z :: Int}
我有一些函式都采用相同的輸入,并且可能無法計算欄位:
data Input
getX, getY, getZ :: Input -> Maybe Int
我可以撰寫一個函式來嘗試所有這三個欄位建構式:
v3 :: Input -> Maybe Vec3
v3 i = liftA3 Vec3 (getX i) (getY i) (getZ y)
但是不得不將i輸入傳遞大約三遍有點煩人。功能本身是一個適用函子,所以人可以代替foo x = bar (f x) (g x) (h x)用foo = liftA3 bar f g h。
在這里,我的bar是liftA3 Vec3,所以我可以寫
v3' :: Input -> Maybe Vec3
v3' = liftA3 (liftA3 Vec3) getX getY getZ
但這有點惡心,當我們以這種方式(((->) Input)和Maybe)使用組合應用程式時,就有了Compose處理這種事情的新型別。有了它,我可以寫
v3'' :: Input -> Maybe Vec3
v3'' = getCompose go
where go = liftA3 Vec3 x y z
x = Compose getX
y = Compose getY
z = Compose getZ
好的,這并不是一個很好的字符節省,但我們現在正在使用一個組合函子而不是兩個,這很好。我想我可以用它coerce來贏回一些字符:畢竟,x它只是圍繞 的新型包裝器getX,對于其他領域也是如此。所以我想我可以強迫liftA3接受三個Input -> Maybe Vec3而不是接受三個Compose ((->) Input) Maybe Vec3:
v3''' :: Input -> Maybe Vec3
v3''' = getCompose go
where go = coerce liftA3 Vec3 getX getY getZ
但是,這并不作業,產生的錯誤資訊:
tmp.hs:23:14: error:
? Couldn't match representation of type ‘f0 c0’
with that of ‘Input -> Maybe Int’
arising from a use of ‘coerce’
? In the expression: coerce liftA3 Vec3 getX getY getZ
In an equation for ‘go’: go = coerce liftA3 Vec3 getX getY getZ
In an equation for ‘v3'''’:
v3'''
= getCompose go
where
go = coerce liftA3 Vec3 getX getY getZ
|
23 | where go = coerce liftA3 Vec3 getX getY getZ
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我不明白為什么不。我可以寫coerce getX :: Compose ((->) Input) Maybe Int,這很好。通常一個函式可以被強制以使其強制其引數或回傳型別,如
coerce (( ) :: Int -> Int -> Int) (Max (5::Int)) (Min (8::Int)) :: Sum Int
事實上,我可以coerce單獨寫出所有的s:
v3'''' :: Input -> Maybe Vec3
v3'''' = getCompose go
where go = liftA3 Vec3 x y z
x = coerce getX
y = coerce getY
z = coerce getZ
那么為什么不能liftA3強迫自己接受getX而不是coerce getX,允許我使用v3'''?
uj5u.com熱心網友回復:
如果您向 提供應用函子liftA3,則進行以下型別檢查:
v3' :: Input -> Maybe Vec3
v3' = coerce (liftA3 @(Compose ((->) Input) Maybe) Vec3) getX getY getZ
在coerce liftA3沒有任何注釋的情況下,無法推斷要使用的應用函子liftA3。這些甚至都沒有提到型別Compose。它也可能是ReaderT Input Maybe,,Kleisli Maybe Input具有非法實體的另一種型別或更奇特的東西。
在getCompose (coerce liftA3 _ _ _)(您的最后一次嘗試)中,getCompose不約束liftA3( 的“內部” coerce),因為getCompose是 的“外部” coerce。它要求 的結果型別liftA3可強制轉換為Compose ((->) Input) Maybe Vec3,但它可能仍然不等于 。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/387039.html
下一篇:使用由函子引數化的資料型別
