String 在Haskell中将字符串转换为类型构造函数

String 在Haskell中将字符串转换为类型构造函数,string,haskell,types,template-haskell,String,Haskell,Types,Template Haskell,有人知道Haskell中是否有这样一个函数: "Int" -> Int "String" -> String "Bool" -> Bool 它采用类型构造函数名称的字符串表示形式,并将其转换为表达式和模式中的实际类型构造函数 编辑: 我的总体目标是简化如下内容: transExp (Add exp1 exp2) vars = transExp exp1 vars ++ transExp exp2 vars ++ [IAdd] transExp (Sub exp1 e

有人知道Haskell中是否有这样一个函数:

"Int" -> Int

"String" -> String

"Bool" -> Bool
它采用类型构造函数名称的字符串表示形式,并将其转换为表达式和模式中的实际类型构造函数

编辑: 我的总体目标是简化如下内容:

transExp (Add exp1 exp2) vars
  = transExp exp1 vars ++ transExp exp2 vars ++ [IAdd]

transExp (Sub exp1 exp2) vars
  = transExp exp1 vars ++ transExp exp2 vars ++ [ISub]

转换为单个模式匹配,因此基本上将Add或Sub转换为字符串,在前面添加一个“I”,然后将其转换回类型。

在哪个上下文中?有模板Haskell和
数据。可键入
,但要获得实际有用的答案,您需要提供更多详细信息。

好吧,问题出在这里

"String" -> String
这在Haskell的土地上简直是胡言乱语,因为
“String”
是一个值,而
String
是一种类型。所以你可以试试这个:

String -> a
这不是你想要的。你应该学习如何阅读类型签名,因为如果你不能阅读类型签名,你将在Haskell严重残疾。上面的类型意味着,“给我一个字符串,我可以给你一个你所要求的任何类型的值。”前奏曲中有一个函数带有这个签名,它被称为
error
,这不是你想要的

听起来像是你想要的东西大致如下:

String -> TypeRep
对不起,没有这样的功能
TypeRep
不会实例化
Read


您实际上想在这里做什么?如果您告诉我们您实际上想做什么,我们可以帮助您解决这个问题,而不是试图帮助解决这个问题。

您不能这样做,因为字符串是运行时数据,必须在编译时完全解析类型。对于您的示例,您最好使用一个helper函数来消除一些重复:

helper exp1 exp2 vars op = transExp exp1 vars ++ transExp exp2 vars ++ [op]
transExp (Add exp1 exp2) vars = helper exp1 exp2 vars IAdd
transExp (Sub exp1 exp2) vars = helper exp1 exp2 vars ISub
但从长远来看,这可能不是很有用,这取决于你有多少病例


通常,模式匹配是针对类型结构运行的,因此必须针对具体类型构造函数在编译类型中详细说明。这是拥有一个真正可靠的静态类型系统所要付出的代价。

这里有一种更好的方法来重构代码,无需任何模板Haskell或反射诡计,只需将
添加
案例合并为一个:

data BinOp = Add | Sub | ...

data Expr = ...
          | BinOp BinOp Expr Expr
          | ...

transExp (BinOp op exp1 exp2) vars
    = transExp exp1 vars ++ transExp exp2 vars ++ [transOp op]
...

transOp Add = IAdd
transOp Sub = ISub

这样,我们使用数据类型直接表示二进制运算符是相关的,因此具有类似的转换。如果您想在某处添加特殊情况,仍然可以在
BinOp Add exp1 exp2
上进行模式匹配。

这可能吗?这些类型不是编译时的概念吗?你要找的函数是什么类型的?我不知道这是否可行,我想它应该是String->a类型,但我真的不确定…看看模板haskell。另外,
IAdd
不是一个类型,而是一个类型构造函数-这是误导性的。看看您的示例,您似乎不想将字符串转换为类型构造函数,而是想将其转换为值构造函数。这可以通过使用
读取(“I”++x)
实现。但不要这样做!如果您使用字符串在不同类型之间转换,则可能会出现问题。他可以使用在编译时运行的模板Haskell代码来实现这一点。他确实可以,但出于这个目的,他说这对我来说似乎有点过分。我想他必须知道所有可能的解决方案。这对他来说是一个很好的机会来学习他能做什么@hammar的解决方案也很棒。他不是在谈论类型名,而是在谈论类型构造函数。他只是想从字符串中生成一些值和模式匹配,以避免使用样板文件。@nponeccop:在问题更改后对答案进行否决投票是不公平的。关于构造器的业务是全新的。很棒的解决方案——比我想象的要简单得多。非常感谢:)那要优雅得多。感谢提醒,它有助于再次缩小,并采取更广阔的视野。