我有文件列表的值和类型,阅读后我需要将它们放入db。为此,我需要提供具有正确类型元组的插入函数,所以我试图用这样的东西转换值
toProperType :: String -> String -> a
toProperType tp val =
case tp of
"string" -> val -- ::String
"int" -> toIntType val -- ::Int64
"bigint" -> toIntType val -- ::Int64
"integer"-> toIntType val
"utcdate"-> toDateType val -- :: UTCTime
"double" -> toDoubleType val -- :: Double
失败了
无法将预期类型'a'与实际类型'Double'匹配 'a'是由
约束的刚性类型变量
我认为是正确的。
实现此功能的正确方法是什么?
也许我需要一些扩展或用TH生成单独的函数(但不知道如何调度它们)
答案 0 :(得分:2)
此处的问题是函数类型中-> a
的含义。如果你的函数实际上有这种类型,那么调用你的函数的人应该能够指定他们选择的具体类型(你甚至可能没有在范围内)然后期望你的函数像工作一样工作
String -> String -> MyCustomType
然而,这显然不是你的想法。你并不是指所有类型a
,我有一个函数......",你的意思是"对于任何两个字符串,都有一些类型{{1我有一个值"。这个想法,你可以选择类型变量而不是调用者,被称为"存在量化"而GHC确实支持它。但是,我并不认为这是你想要做的。毕竟,当你真正使用这个功能时,你可能希望能够判断你是否有a
或UTCTime
或其他东西。既然你不能用存在量化来做这件事(就像你不能在多态函数中对类型变量的情况那样),我们应该创建一个自定义数据类型:
Double
等等。也就是说,为类型可能返回的每个案例列出一个显式构造函数,然后您的函数将读取
data Dyn = String String | Int Int | BigInt Integer | UTCDate UTCTime ...
这是Haskell库处理诸如JSON解析之类的事情的严重程度,或者不是什么让你处于良好的公司状态。现在它输入得很好,无论谁调用此函数只是toProperType :: String -> String -> Dyn
toProperType tp val =
case tp of
"string" -> String val -- ::String
"int" -> Int $ toIntType val -- ::Int64
"bigint" -> BigInt $ toIntType val -- ::Int64
"integer"-> Integer $ toIntType val
"utcdate"-> UTCDate $ toDateType val -- :: UTCTime
"double" -> Double $ toDoubleType val -- :: Double
值的情况,并根据返回的类型决定做什么。