簡體   English   中英

當異構列表的所有元素都是同一類的實例時,如何將函數應用於它們?

[英]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的所有操作都提升到類型類級別,而hMaphFoldr等高階函數不適用於“普通”工作函數,但需要將它們提升到類型類級別作為好。

這里, 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

那么類型推斷不會很好地工作。

關於HList的文檔似乎並不多,而且官方論文看起來也不像是一個很好的通用教程。 也許這篇博文會有所幫助?

暫無
暫無

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

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