有沒有在Haskell中具有相同類型的對列表的任何方法,並使函數遍歷它。例如:不同類型的元組
a = [(1, "uno"), (2, True), (3, 5)]
甲要應用根據第二值的類型,如,用於評估對f :: [(Int, #)] -> [a].
有沒有在Haskell中具有相同類型的對列表的任何方法,並使函數遍歷它。例如:不同類型的元組
a = [(1, "uno"), (2, True), (3, 5)]
甲要應用根據第二值的類型,如,用於評估對f :: [(Int, #)] -> [a].
只需將值包裝在求和類型中。例如,
data StringOrBoolOrInt =
StringOrBoolOrInt_String String |
StringOrBoolOrInt_Bool Bool |
StringOrBoolOrInt_Int Int
a :: [(Int, StringOrBoolOrInt)]
a =
[
(1, StringOrBoolOrInt_String "uno"),
(2, StringOrBoolOrInt_Bool True),
(3, StringOrBoolOrInt_Int 5)
]
To a first approximation的組合的功能的東西的函數,不,這是不可能的。首先對值進行標準化,例如通過在將每個第二個參數放到元組中之前對其應用一些類 - 多態函數。
正如其他人所說的那樣,這個問題沒有解決方案。但是你真正的問題是你的數據不是由元組列表描述的 - 根據定義,列表是同質的(所有元素都包含相同的類型),而你的數據是異構的。
如果要根據類型編寫函數,必須以某種方式將類型存儲在類型級別上。
data Prod f (xs :: [a]) where
P0 :: Prod f '[]
(:>) :: f x -> Prod f xs -> Prod f (x ': xs)
infixr 5 :>
或更一般地爲Prod ((,) Integer) xs
類型xs
一些列表:
你的示例數據實際上是由類型Prod ((,) Integer) '[String, Bool, Integer]
,其中Prod
是以下類型描述。
你的榜樣值此時
a = (1, "uno") :> (2, True) :> (3, 5) :> P0
您可以對這些類型使用普通方法分支 - 即一個類型的類。假設一個有這樣一類:
class HasFoo x where
foo :: x -> Integer
instance HasFoo String where foo = fromIntegral . length
instance HasFoo Bool where foo = fromIntegral . fromEnum
instance HasFoo Integer where foo = id
可以應用這樣的foo
功能,爲您的產品
type family All (c :: k -> Constraint) (xs :: [k]) :: Constraint where
All c '[] =()
All c (x ': xs) = (c x, All c xs)
-- example operation: add everything
fooProd :: All HasFoo xs
=> Prod ((,) Integer) xs
-> Integer
fooProd P0 = 0
fooProd ((i, x) :> ps) = i + foo x + fooProd ps
的每一個元素這需要一些GHC擴展,至少TypeFamilies
,GADTs
,ConstraintKinds
,DataKinds
, PolyKinds
。
如果沒有'ImpredicativeTypes'擴展名,目前[並不真正工作](http://stackoverflow.com/q/33741334/465378),我不認爲這是可能的。 –
@AlexisKing'ImpredicativeTypes'不會幫你在這裏。 Impredicativity允許你通過'forall'量化的類型來參數化類型,例如做一個多態函數的_homogeneous_列表。 OP想要構建一個單形元組的_heterogeneous_列表。 –
@jonaprieto你想達到什麼目的?最簡單的方法是構建一個sum類型,並對這些值進行運行時實例分析:'a :: [(Int,Bool String)]' –