haskell - 如何在 Haskell 中工作的返回类型上获得 'unpredictable' 重载?

标签 haskell polymorphism overloading typeclass

我有一些类型的实例。我们称它们为 A、B 和 C。它们都是类型类 X 的实例。现在我想创建一个单独的函数 create给定一些输入(比如说一个字符串),它会创建一个 A、B 或 C 的实例。类型系统无法知道什么输入将给出什么类型。那是 Haskell 不喜欢的东西,我想我知道答案,但我想确定一下。我得到的当前错误是:

• Couldn't match expected type ‘c’ with actual type ‘GCCCommand’
  ‘c’ is a rigid type variable bound by
    the type signature for:
      compiler :: forall c. CompilerCommand c => String -> c
    at src/System/Command/Typed/CC.hs:29:1-44
• In the expression: gcc path
  In an equation for ‘compiler’:
      compiler path
        | exe == "g++" || exe == "gcc" || exe == "cc" || exe == "cpp"
        = gcc path
        where
            exe = takeFileName path
• Relevant bindings include
    compiler :: String -> c
      (bound at src/System/Command/Typed/CC.hs:31:1)

这是否意味着,正如我所怀疑的那样,在这种特殊情况下不可能重载返回类型,因为编译器无法预先知道数据在内存中的外观?你将如何实现这个功能?我正在考虑创建如下内容:

data SuperX = SuperA A | SuperB B | SuperC C

create :: String -> SuperX
-- create can now be implemented

instance X SuperX where
  -- a lot of boilerplate code ...

但是,样板代码表明它可以做得更好。这真的是最好的方法吗?

最佳答案

这取决于你需要用它做什么。

如果您以后的处理不关心它是否得到 A , 一个 B , 或 C , 只是它得到了实现 X 的东西...

restOfProgram :: X a => a -> ThingIWantToCompute

然后你可以使用继续传递:
parseABC :: (X a => a -> r) -> String -> Maybe r
parseABC f "A" = Just (f A)
parseABC f ('B':xs) = Just (f (B xs))
parseABC f ('C':xs) = Just (f (C (read xs)))
parseABC _ _ = Nothing

或存在的数据包装器:
data SomeX where
  SomeX :: X t => t -> SomeX

parseABC :: String -> Maybe SomeX
parseABC "A" = Just (SomeX A)
parseABC ('B':xs) = Just (SomeX (B xs))
parseABC ('C':xs) = Just (SomeX (C (read xs)))
parseABC _ _ = Nothing

restOfProgram' :: SomeX -> ThingIWantToCompute
restOfProgram' (SomeX t) = restOfProgram t

如果后面的处理对A有不同的路径, BC ,您可能希望返回一个总和类型,如 SuperX .

关于haskell - 如何在 Haskell 中工作的返回类型上获得 'unpredictable' 重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53837669/

相关文章:

c++ - 普通数据对象的多态性的正确方法是什么?

c++ - 为什么具有相同名称但不同签名的多个继承函数不会被视为重载函数?

Java:如何在枚举中使用构造函数重载?

performance - Haskell:在大列表中找到最大值时堆栈溢出

haskell - 寻找组合

parsing - 可逆状态单子(monad)(和解析器)

c++ - 包含带有模板对象的容器的类

haskell - 自由 monad 和类型约束

haskell - 如何生成使用 MVar 的数据类型?

c# - 泛型和从不同类调用重载方法 - 优先级问题