【问题标题】:Why do these expressions have different levels of ambiguity?为什么这些表达有不同程度的歧义?
【发布时间】:2017-07-23 22:03:52
【问题描述】:

我正在写这个函数:

||| Returns the ten largest values in the list.
top_ten : Ord a => List a -> List a

我的第一次尝试是使用函数组合实现pointfree

top_ten = take 10 . reverse . sort

但这给出了以下错误:

Main.idr:3:9:When checking right hand side of top_ten with expected type
        List a -> List a

Can't disambiguate name: Prelude.List.take, Prelude.Stream.take

我的第二次尝试是一个简单直接的实现:

top_ten xs = take 10 (reverse (sort xs))

这行得通,就像这些:

top_ten xs = take 10 $ reverse $ sort xs
top_ten xs = take 10 (reverse $ sort xs)
top_ten xs = take 10 $ reverse . sort $ xs
top_ten xs = take 10 (reverse . sort $ xs)

但是,这些不是:

top_ten xs = take 10 . reverse $ sort xs
top_ten xs = take 10 . reverse . sort $ xs
top_ten xs = take 10 $ (reverse . sort) xs
top_ten xs = (take 10 . reverse) (sort xs)
top_ten xs = take 10 ((reverse . sort) xs)

这里到底发生了什么? 是什么导致这些等价表达式具有不同程度的歧义?

【问题讨论】:

  • Idris 类型推断的能力还不如 Haskell/Agda。

标签: overloading type-inference ambiguous idris function-composition


【解决方案1】:

根据您在范围内的导入(或前奏曲中的函数),Idris 无法选择正确的函数,正如 András Kovács 在他的评论中所说的那样。

不过,您可以帮助 idris:

top_ten: Ord a => List a -> List a
top_ten = with Prelude.List take 10 . reverse . sort

【讨论】:

  • 谢谢!这并不完全是“为什么”的答案,但我不知道with 语法。您能否发布此语法的文档链接?我所能找到的只是在homepagethis Google Groups post 上提及它。
  • 我在文档中也找不到任何内容。这只是我偶然发现的,可能是通过阅读邮件列表。
  • 是不是因为.的定义被键入允许依赖应用?如果您定义自己的不允许依赖类型函数的组合版本(即仅(b -> c) -> (a -> b) -> a -> c),重载决议是否成功?
  • @Cactus 我不确定你的意思;这是. as it is defined in Idris 的确切类型签名。
  • @SamEstep:对不起,你完全正确。出于某种原因,我认为它的类型类似于({x : a} -> (y : b x) -> c y) -> (g : (x : a) -> b x) -> ((x : a) -> c (g x))
猜你喜欢
  • 2013-03-21
  • 2015-09-30
  • 2013-07-10
  • 1970-01-01
  • 2015-10-06
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
相关资源
最近更新 更多