【问题标题】:Could not deduce (a ~ Set.Set (Set.Set a))无法推断(a~Set.Set(Set.Set a))
【发布时间】:2013-10-31 00:14:30
【问题描述】:

我需要有关以下错误的帮助。基本上对于给定的项目列表,我想创建一个函数来检查项目是否在该列表中。为了做到这一点,我将列表变成一个集合,然后围绕该集合创建一个闭包。

toAccept :: Ord a => [a] -> (a -> Bool)
toAccept xs =
    let xset = Set.fromList xs in
    let
    -- accept:: Ord a => a -> Bool
    accept x = Set.member xset x in 
    accept

我得到的是

Could not deduce (a ~ Set.Set (Set.Set a))
from the context (Ord a)
  bound by the type signature for
             toAccept :: Ord a => [a] -> a -> Bool
  at Tokens.hs:6:13-39
  `a' is a rigid type variable bound by
      the type signature for toAccept :: Ord a => [a] -> a -> Bool
      at Tokens.hs:6:13
Expected type: a -> Bool
  Actual type: Set.Set (Set.Set a) -> Bool
In the expression: accept
In the expression: let accept x = Set.member xset x in accept
In the expression:
  let xset = Set.fromList xs in
  let accept x = Set.member xset x in accept

我做错了什么?

【问题讨论】:

  • member 中的参数顺序倒数。
  • 该死!那是愚蠢的。谢谢...
  • 我也希望你知道elem
  • @n.m.如果他查询很多元素elemO(n) 每个查询但toAccept 在构造期间是O(n) 但每个查询只有O(log(n))
  • 您也可以将最后四行替换为(`Set.member` xset)

标签: haskell


【解决方案1】:

你的论点失败了

let accept x = Set.member x xset in accept

通常,在 haskell 函数中,数据结构排在最后,因为这使它适合无点样式。有关更多信息,请参阅here

一种可能更好的写法是

toAccept' :: Ord a => [a] -> a -> Bool
toAccept' = flip Set.member . Set.fromList

这里我们利用了 Haskell 的柯里化功能,因为 [a] -> a -> Bool[a] -> (a -> Bool) 相同。我们实际上可以编写我们的函数,就好像它接收两个参数并且不接受一个并返回一个函数,因为在 Haskell 中,这些选项是相同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2013-10-05
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多