从字符串

时间:2016-03-25 12:52:45

标签: haskell generic-programming template-haskell

我有文件列表的值和类型,阅读后我需要将它们放入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生成单独的函数(但不知道如何调度它们)

1 个答案:

答案 0 :(得分:2)

此处的问题是函数类型中-> a的含义。如果你的函数实际上有这种类型,那么调用你的函数的人应该能够指定他们选择的具体类型(你甚至可能没有在范围内)然后期望你的函数像工作一样工作

String -> String -> MyCustomType

然而,这显然不是你的想法。你并不是指所有类型a,我有一个函数......",你的意思是"对于任何两个字符串,都有一些类型{{1我有一个值"。这个想法,你可以选择类型变量而不是调用者,被称为"存在量化"而GHC确实支持它。但是,我并不认为这是你想要做的。毕竟,当你真正使用这个功能时,你可能希望能够判断你是否有aUTCTime或其他东西。既然你不能用存在量化来做这件事(就像你不能在多态函数中对类型变量的情况那样),我们应该创建一个自定义数据类型:

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 值的情况,并根据返回的类型决定做什么。