【发布时间】:2016-03-22 20:20:40
【问题描述】:
考虑下面的代码:
t1 :: [Int] -> (Int,String)
t1 xs = (sum xs,show $ length xs)
t2 :: [Int] -> (Int,String)
t2 xs = (length xs, (\x -> '?') <$> xs)
t3 :: [Int] -> (Char,String)
t3 (x:xs) = ('Y',"1+" ++ (show $ length xs))
t3 [] = ('N',"empty")
这三个函数的类型只有部分变化——它们完全可用,无需知道它们生成的元组的第一个组件的类型。这意味着我可以对它们进行操作而无需引用该类型:
fnListToStrs vs fs = (\x -> snd $ x vs) <$> fs
将这些定义加载到 GHCi 中,所有三个函数都作为 fnListToStrs 的参数独立工作,实际上我可以传入一个包含 t1 和 t2 的列表,因为它们具有相同的类型:
*Imprec> fnListToStrs [1,2] [t1,t2]
["2","??"]
*Imprec> fnListToStrs [1,2] [t3]
["1+1"]
但我不能同时通过所有 3 个,即使类型的分歧实际上与执行的计算无关:
*Imprec> fnListToStrs [1,2] [t1,t2]
["2","??"]
*Imprec> fnListToStrs [1,2] [t3]
["1+1"]
我觉得使这项工作与存在或暗示类型有关,但是在使用我希望 fnListToStrs 能够采用的类型声明时,这两种扩展都对我不起作用,即:
fnListToStrs :: [Int] -> [forall a.[Int]->(a,String)] -> [String]
还有其他方法可以实现吗?
【问题讨论】:
标签: haskell polymorphism quantifiers