有没有在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)]' –