[英]How can I apply a function to all elements of a heterogeneous list when they are all instances of the same class?
Prelude> import Data.HList
Prelude Data.HList> let myList = False .*. 'c' .*. HNil
Prelude Data.HList> myList
H[False,'c']
Prelude Data.HList> :t myList
myList :: HList '[Bool, Char]
現在,
Prelude Data.HList> hMap show myList
<interactive>:5:1: error:
* Couldn't match type `Bool' with `Char'
arising from a use of `hMap'
* In the expression: hMap show myList
In an equation for `it': it = hMap show myList
我希望 H["False","'c'"] 類型為 H[String,String]
我知道 show 函數對於 Bool 類型和 Char 類型確實不是同一個實例,但是如果這樣的操作是不可能的,我就不明白這個 HList 的意義。
如何對這些類型共享實例化的實例的功能部分進行一般操作?
正如其他人在評論中所說的那樣, HList
有一些替代品可能更容易使用。
無論如何,我認為你應該寫:
hMap HShow myList
HList 包的工作方式,對HList
的所有操作都提升到類型類級別,而hMap
和hFoldr
等高階函數不適用於“普通”工作函數,但需要將它們提升到類型類級別作為好。
這里, HShow
是使用代理數據類型和ApplyAB
類的實例定義的:
data HShow = HShow
instance (String ~ string, Show a) => ApplyAB HShow a string where
applyAB _ x = show x
如果你有自己的函數:
add5 :: (Num a) => a -> a
add5 = (+5)
您需要為其定義類似的數據類型和實例:
data HAdd5 = HAdd5
instance (Num a, a ~ b) => ApplyAB HAdd5 a b where
applyAB _ x = add5 x
進而:
> let myList = (10.1 :: Double) .*. (6 :: Int) .*. HNil
> print $ hMap HAdd5 myList
H[15.1,11]
編寫這些實例可能有點棘手。 如果上述實例以更自然的形式編寫:
instance (Num a) => ApplyAB HAdd5 a a where
applyAB _ x = add5 x
那么類型推斷不會很好地工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.