为什么这些表达式有不同程度的歧义?

时间:2017-07-23 22:03:52

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

我正在写这个函数:

||| 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)

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

1 个答案:

答案 0 :(得分:2)

根据你在范围内的进口(或Prelude的功能),Idris无法选择正确的功能,AndrásKovács在评论中说。

但你可以帮助idris:

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