从字符串转换为类型值
Convert to typed value from String
我有一个包含值和类型列表的文件,在阅读它们之后我需要将它们放入数据库中。为此,我需要为插入函数提供正确类型的元组,所以我试图用这样的东西转换值
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
失败
Couldn't match expected type ‘a’ with actual type ‘Double’
‘a’ is a rigid type variable bound by
我认为是正确的。
实现此功能的正确方法是什么?
也许我需要一些扩展或使用 TH 生成单独的函数(但不确定如何调度它们)
这里的问题是 -> a
在你的函数类型中的含义。如果你的函数实际上有这种类型,那么 调用 你的函数的人应该能够指定他们选择的具体类型(你甚至可能不在范围内)然后期待你的功能就像它具有类型
一样工作
String -> String -> MyCustomType
但这显然不是您的初衷。你不是说"for all types a
, I have a function ...",你是说"For any two strings, there is some type a
for which I have a value"。这个想法,你可以选择类型变量而不是调用者,被称为 "existential quantification" 并且 GHC 确实支持它。但是我真的不认为那是你想要做的。毕竟,当您实际使用此函数时,您可能希望能够判断是否返回了 UTCTime
或 Double
之类的东西。因为你不能用存在量化来做到这一点(就像你不能在多态函数中对类型变量进行大小写一样)我们应该创建一个自定义数据类型:
data Dyn = String String | Int Int | BigInt Integer | UTCDate UTCTime ...
等等。也就是说,您为您的类型可能 return 的每种情况列出一个显式构造函数,然后您的函数将读取
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
这就是 Haskell 库处理诸如 JSON 解析之类的事情的严肃程度,所以你们是好伙伴。现在它的类型很好,调用此函数的人只是根据 Dyn
值计算大小写,并根据 returned 类型决定要做什么。
我有一个包含值和类型列表的文件,在阅读它们之后我需要将它们放入数据库中。为此,我需要为插入函数提供正确类型的元组,所以我试图用这样的东西转换值
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
失败
Couldn't match expected type ‘a’ with actual type ‘Double’ ‘a’ is a rigid type variable bound by
我认为是正确的。
实现此功能的正确方法是什么?
也许我需要一些扩展或使用 TH 生成单独的函数(但不确定如何调度它们)
这里的问题是 -> a
在你的函数类型中的含义。如果你的函数实际上有这种类型,那么 调用 你的函数的人应该能够指定他们选择的具体类型(你甚至可能不在范围内)然后期待你的功能就像它具有类型
String -> String -> MyCustomType
但这显然不是您的初衷。你不是说"for all types a
, I have a function ...",你是说"For any two strings, there is some type a
for which I have a value"。这个想法,你可以选择类型变量而不是调用者,被称为 "existential quantification" 并且 GHC 确实支持它。但是我真的不认为那是你想要做的。毕竟,当您实际使用此函数时,您可能希望能够判断是否返回了 UTCTime
或 Double
之类的东西。因为你不能用存在量化来做到这一点(就像你不能在多态函数中对类型变量进行大小写一样)我们应该创建一个自定义数据类型:
data Dyn = String String | Int Int | BigInt Integer | UTCDate UTCTime ...
等等。也就是说,您为您的类型可能 return 的每种情况列出一个显式构造函数,然后您的函数将读取
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
这就是 Haskell 库处理诸如 JSON 解析之类的事情的严肃程度,所以你们是好伙伴。现在它的类型很好,调用此函数的人只是根据 Dyn
值计算大小写,并根据 returned 类型决定要做什么。