gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 15:39:01 25 4
gpt4 key购买 nike

我有一些类型的实例。我们称它们为 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com