Haskell函数,它接受一个类型和一个值,并检查value是否具有该类型

Dan*_*son 10 haskell types

我正在尝试在Haskell中创建一个简单的Scheme解释器.作为其中的一部分,我正在实现一些原始运算符,如数字?,字符串?等等

我有这样的代码:

isNumber :: [LispVal] -> LispVal
isNumber ([Number n]) = Bool True
isNumber            _ = Bool False

isString :: [LispVal] -> LispVal
isString ([String n]) = Bool True
isString            _ = Bool False
Run Code Online (Sandbox Code Playgroud)

而我喜欢的是类似的东西

isType :: ?? -> [LispVal] -> LispVal
isType (typeName [typeName n]) = Bool True
isType                       _ = Bool False
Run Code Online (Sandbox Code Playgroud)

换句话说,我想通过说"isType Number"来创建isNumber的等价物.这有可能吗?我很难在谷歌找到类似的东西,也许是因为我不知道该怎么称呼这种情况.

C. *_*ann 8

我假设你有类似这样的类型:

data LispVal = String String | Number Double -- &c....
Run Code Online (Sandbox Code Playgroud)

...你想测试一个是否的函数LispVal值是一个特殊的构造函数(String,Number基于一些说法,&C).

不幸的是,实际上并没有一种直截了当的通用方法.

你可以求助于字符串比较:

getTypeName :: LispVal -> String
getTypeName (String _) = "String"
getTypeName (Number _) = "Number"

isType :: String -> [LispVal] -> LispVal
isType name [val] = Bool (name == getTypeName val)
isType _ _ = Bool False
Run Code Online (Sandbox Code Playgroud)

或者你可以比较两个LispVals 的类型:

sameType :: LispVal -> LispVal -> LispVal
sameType (String _) (String _) = Bool True
sameType (Number _) (Number _) = Bool True
sameType _ _ = Bool False
Run Code Online (Sandbox Code Playgroud)

...然后创建一个虚拟值以与for进行比较isType.

你也可以创建一个"类型"值并对LispVals 实现一种反射,然后根据这些进行比较:

data LispType = LispString | LispNumber | LispType

getType :: LispVal -> LispVal
getType (String _) = Type LispString
getType (Number _) = Type LispNumber
getType (Type _) = Type LispType

isType :: LispVal -> [LispVal] -> LsipVal
isType t [v] = isEqual t (getType v)
isType _ _ = Bool False
Run Code Online (Sandbox Code Playgroud)

其中一种方法的一些变化可能是您的最佳选择.还有其他方法,基于Haskell的更高级功能,但除非解释语言的类型与Haskell的类型更紧密地联系,否则它们可能不值得麻烦.

  • `getType(Type _)= Type LispType` ...类型的类型是类型类型?O_O? (2认同)