haskell - 在haskell中返回不同的类型

标签 haskell types

我是 Haskell 的新手,正在从事一个项目,其中包含以下代码:

data Nested a = Elem a | Nested [Nested a] deriving (Eq, Show)
data Symbol a = Value a | Transformation (a -> a -> a) deriving (Show)


toSymbol :: [Char] -> Nested (Symbol Integer)
toSymbol x  
|all isDigit x = Elem (Value (strToInt x))
|x == "+" = Elem (Transformation (\x y -> x + y))

有什么方法可以避免将此函数的类型限制为 Nested (Symbol Integer)?我想使用 Symbol 来表示许多不同的类型,并有一个函数 toSymbol something along the lines of the following:

toSymbol x  
|x == "1" = Elem (Value 1)
|x == "+" = Elem (Transformation (\x y -> x + y))
|x == "exampleword" = Elem (Value "word")
|x == "concatenate()" = Elem (Transformation concatTwoStrings)

我不知道这样的函数的类型签名是什么。我可以做些什么来获得与此类似的功能吗?

最佳答案

你无法弄清楚类型签名的原因是因为你试图做的是“使函数的返回类型取决于传递的字符串的值,也就是依赖类型编程”,字符串将仅在运行时可用。

所以基本上,如果您尝试说:toSymbol::String -> Nested (Symbol a)a 取决于字符串的运行时值,这就是为什么编译器提示它。

有很多方法可以优化您的类型,以便所有部分组合在一起,一个可能的解决方案是使用一种新类型,它指定一个符号可能具有的不同类型的值。下面是示例:

data Nested a = Elem a | Nested [Nested a] deriving (Eq, Show)
data Symbol a = Value a | Transformation (a -> a -> a)
data SymbolType = SInteger Integer | SString String

addSymbols :: SymbolType -> SymbolType -> SymbolType
addSymbols (SInteger a) (SInteger b) = SInteger (a+b)
addSymbols _ _ = error "Not possible"

concatSymbols :: SymbolType -> SymbolType -> SymbolType
concatSymbols (SString a) (SString b) = SString (a++b)
concatSymbols _ _ = error "Not possible"

toSymbol :: String -> Nested (Symbol SymbolType)
toSymbol x  
  |x == "1" = Elem (Value (SInteger 1))
  |x == "+" = Elem (Transformation addSymbols)
  |x == "exampleword" = Elem (Value (SString "word"))
  |x == "concatenate()" = Elem (Transformation concatSymbols)

关于haskell - 在haskell中返回不同的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19674235/

相关文章:

haskell - 如何将 CPPFLAGS 和 LDFLAGS 添加到我的 cabal 文件中?

haskell - 在 Haskell 中将 [IO Int] 转换为 IO [Int]?

haskell - new-template.cabal 和 stack.yaml 的区别

sql - 如何添加时间戳和整数类型的两列

python - 如何在 python 中将分类列转换为整数列? (与南)

java - 对于某些 Java 类型,将 Java 类型对象转换为字符串失败

Haskell 按列表索引过滤

haskell - 将类型作为参数传递给 Haskell 中的函数?

MySQL - 使用什么类型的范围(例如 10-20 厘米)

C# 相当于 VB6 'Type'