Ответ 1
Я предполагаю, что у вас есть что-то вроде этого:
data LispVal = String String | Number Double -- &c....
... и вам нужна функция, которая проверяет, является ли значение 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
Или вы можете сравнить типы двух LispVal
s:
sameType :: LispVal -> LispVal -> LispVal
sameType (String _) (String _) = Bool True
sameType (Number _) (Number _) = Bool True
sameType _ _ = Bool False
... и затем создайте фиктивное значение для сравнения с isType
.
Вы также можете сделать "тип" и реализовать свое отражение на LispVal
s, а затем сравнить на основе:
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
Некоторые варианты одного из этих подходов, вероятно, являются вашим лучшим вариантом. Существуют и другие способы, основанные на более продвинутых функциях Haskell, но они, вероятно, не стоят проблем, если интерпретируемые типы языков гораздо более тесно связаны с типами Haskell.