【问题标题】:Not typed empty list : Haskell未输入空列表:Haskell
【发布时间】:2018-01-09 11:26:52
【问题描述】:

我只是尝试在 Haskell 中编写我能想象到的最简单的可能函数,并收到此错误消息。神奇的是,它只在我尝试评估 myHead 以获得空列表时出现。我做错了什么?

module Main 
  where

myHead :: [a] -> Maybe a
myHead [] = Nothing
myHead (x:_) = Just x

main = do
print (myHead [])

当我从一个文件运行它时,我得到这个输出:

main.hs:15:1: error:
  • Ambiguous type variable ‘a0’ arising from a use of ‘print’
    prevents the constraint ‘(Show a0)’ from being solved.
    Probable fix: use a type annotation to specify what ‘a0’ should be.
 These potential instances exist:
   instance Show Ordering -- Defined in ‘GHC.Show’
   instance Show Integer -- Defined in ‘GHC.Show’
   instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
    ... plus 22 others
     ...plus 12 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
 • In a stmt of a 'do' block: print (myHead [])
  In the expression: do { print (myHead []) }
  In an equation for ‘main’: main = do { print (myHead []) }
  <interactive>:3:1: error:
   • Variable not in scope: main
   • Perhaps you meant ‘min’ (imported from Prelude)

【问题讨论】:

  • 如果你在 shell 中运行它,那么你定义了多个 myHead 函数。
  • 您的标题具有误导性。你的错误在哪里说“非详尽的模式?”请相应更改。

标签: list haskell maybe


【解决方案1】:

myHead 没有问题,如果你用了也会遇到同样的问题:

main = do
   print Nothing

这里的问题是NothingmyHead [] 对于任何a 都有一个多态类型Maybe a。然后,调用print 来写入该值。为此,print 必须要求 Maybe a 可转换为字符串:它通过要求 Show (Maybe a) 来做到这一点,而 Show a 又要求 Show a

但是,Show a 没有通用实例:编译器现在需要知道 a 是什么,然后才能将其转换为字符串。

注意这一点

print (Just 3 :: Maybe Int) -- OK
print (Just id :: Maybe (Int->Int)) -- Not OK! Functions can not be printed

解决方案是为您的代码使用具体类型

main = do
   print (myHead [] :: Maybe Int) -- or any other showable type

【讨论】:

  • 我想知道类型系统需要什么才能识别show Nothing 的值与具体类型无关。
  • @chepner 这还需要证明print 的参数确实是Nothing,这通常是不可行的。尽管如此,在可行的情况下,拥有这样一个“部分依赖”的类型系统确实很有趣。如果我们有子类型,我们可以让 'Nothing` 在子类型上有自己的子类型 Maybe a', and define Show`。 (不过,这会打开新的蠕虫罐,例如重叠实例。)
  • 我认为这与依赖类型有关。我只考虑像show Nothing 这样的直接用途,而不是show expressionThatMightReduceToNothing,所以我看到这是最大的绊脚石:类型检查器的工作太多(无法确定)。
  • @MártonKardos 如果这个答案解决了你的问题,你也应该接受它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-26
  • 2017-08-05
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-01
相关资源
最近更新 更多