gpt4 book ai didi

haskell - 当我添加不相关的定义时,为什么会在此程序中出现类型错误?

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

我给同事看 Free当我遇到一种奇怪的 GHC 行为时,我真的不明白。这是一个简单的、人为的类型检查程序:

import Prelude hiding (readFile, writeFile)
import Control.Monad.Free
import Data.Functor.Sum

data FileSystemF a
= ReadFile FilePath (String -> a)
| WriteFile FilePath String a
deriving (Functor)

data ConsoleF a
= WriteLine String a
deriving (Functor)

data CloudF a
= GetStackInfo String (String -> a)
deriving (Functor)

type App = Free (Sum FileSystemF (Sum ConsoleF CloudF))

readFile :: FilePath -> App String
readFile path = liftF (InL (ReadFile path id))

writeFile :: FilePath -> String -> App ()
writeFile path contents = liftF (InL (WriteFile path contents ()))

我尝试添加另一个定义,但不太正确:
writeLine :: String -> App ()
writeLine line = liftF (InR (WriteLine line ()))

这里的问题是我错过了另一个 InL .正确的定义应该是这样的:
writeLine :: String -> App ()
writeLine line = liftF (InR (InL (WriteLine line ())))

然而,这不是重点。对我来说奇怪的是 GHC 在我添加第一个不正确的 writeLine 定义时产生的类型错误。 .具体来说,它产生了两种类型的错误:
/private/tmp/free-sandbox/src/FreeSandbox.hs:26:27: error:
• Couldn't match type ‘ConsoleF’ with ‘Sum ConsoleF CloudF’
arising from a functional dependency between constraints:
‘MonadFree
(Sum FileSystemF (Sum ConsoleF CloudF))
(Free (Sum FileSystemF (Sum ConsoleF CloudF)))’
arising from a use of ‘liftF’ at src/FreeSandbox.hs:26:27-66
‘MonadFree
(Sum FileSystemF ConsoleF)
(Free (Sum FileSystemF (Sum ConsoleF CloudF)))’
arising from a use of ‘liftF’ at src/FreeSandbox.hs:29:18-48
• In the expression: liftF (InL (WriteFile path contents ()))
In an equation for ‘writeFile’:
writeFile path contents = liftF (InL (WriteFile path contents ()))
|
26 | writeFile path contents = liftF (InL (WriteFile path contents ()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/private/tmp/free-sandbox/src/FreeSandbox.hs:29:18: error:
• Couldn't match type ‘Sum ConsoleF CloudF’ with ‘ConsoleF’
arising from a functional dependency between:
constraint ‘MonadFree
(Sum FileSystemF ConsoleF)
(Free (Sum FileSystemF (Sum ConsoleF CloudF)))’
arising from a use of ‘liftF’
instance ‘MonadFree f (Free f)’ at <no location info>
• In the expression: liftF (InR (WriteLine line ()))
In an equation for ‘writeLine’:
writeLine line = liftF (InR (WriteLine line ()))
|
29 | writeLine line = liftF (InR (WriteLine line ()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

两个错误中的第二个(第 29 行的那个)是有道理的。这是我预期的错误。但是第 26 行的错误完全让我感到困惑。 writeFile的定义是正确的!添加我对 writeLine 的错误定义应该对 writeFile 没有任何影响, 正确的?这是怎么回事?

我能够在 GHC 8.0.2 和 GHC 8.2.1 上重现这一点。我想知道这是否是 GHC 中的错误(以便我可以报告),或者这是我不理解的代码问题。

最佳答案

这是一个 GHC 错误。它已在提交 48daaaf0bba279b6e362ee5c632de69ed31ab65d (Don't report fundep wanted/wanted errors) 中修复,根据瑞安斯科特。

关于haskell - 当我添加不相关的定义时,为什么会在此程序中出现类型错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46595162/

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