gpt4 book ai didi

haskell - 为什么 GHC 不对 "No match in record selector"异常给出编译时警告?

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

当我运行这个错误的代码时......

data Person = Adult { pName :: String}
| Kid { pName :: String
, pAge :: Int
} deriving Show

getAge :: Person -> Int
getAge p = pAge p

getName :: Person -> String
getName p = pName p

main :: IO ()
main = do

let p1 = Kid "fred" 5
p2 = Adult "john"
ps = [p1, p2]

names = map getName ps
ages = map getAge ps

putStrLn $ "names: " ++ show names
putStrLn $ "ages: " ++ show ages

...我在 ghci 中得到了这个:
names: ["fred","john"]

ages: [5,* * * Exception: No match in record selector pAge

我知道如何避免这个错误,但我想知道为什么用“ghc -Wall”编译没有警告我这个问题。是否有其他工具可以帮助我防止此类错误?

最佳答案

Is there [a] tool that can help me to prevent this type of error?



不,但可能有。

如您所知,记录语法会自动生成与您定义的属性同名的 getter。因此代码
data Person = Adult { pName :: String}
| Kid { pName :: String
, pAge :: Int
} deriving Show

创建函数 pName :: Person -> StringpAge :: Person -> Int .现在,假设 Haskell 有子类型。如果是,那么 Kid可能是 Person 的子类型, 和 pAge可能有更合适的类型 Kid -> String .然而,Haskell 没有子类型,因此没有 Kid类型。

现在,鉴于 Person -> String是我们可以给 pAge 的最具体的类型,为什么不警告 pAge是编译时的偏函数吗?让我通过引用List示例来转移问题
data List a = Cons { head :: a, tail :: List a } | Empty

在本例中, headtail是偏函数:非空列表的两个组件,但是(由于 Haskell 缺少子类型)空列表上的无意义访问器。那么,为什么默认没有警告呢?好吧,默认情况下,您知道自己编写的代码。如果您使用 unsafePerformIO,编译器不会提供警告。 ,因为你是这里的程序员,你应该负责任地使用这些东西。

所以 tl;博士 :如果你想要这里的警告:
getAge :: Person -> Int
getAge p = pAge p

那么你就不走运了,因为类型系统没有足够的信息来推断这是一个问题。

如果你想要这里的警告:
data Person = Adult | Kid { pAge :: Int }

那么我确信实现起来很简单:只需检查给定字段是否存在于某些构造函数中,但不存在于其他构造函数中。但我不认为这个警告对每个人都有广泛的用处。有些人可能会提示这只是噪音。

关于haskell - 为什么 GHC 不对 "No match in record selector"异常给出编译时警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10393764/

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