0

次のエラーについて助けが必要です。基本的に、アイテムの特定のリストに対して、アイテムがそのリストにあるかどうかをチェックする関数を作成したいと考えています。そのために、リストをセットに変換し、そのセットの周りにクロージャーを作成します。

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

私は何を間違っていますか?

4

1 に答える 1

2

あなたの議論は失敗に終わりました

let accept x = Set.member x xset in accept

原則として、haskell 関数ではデータ構造が最後に来ます。詳細については、こちらを参照してください。

これを書く潜在的により良い方法は次のとおりです

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

[a] -> a -> Boolは と同じなので、ここでは Haskell のカリー化機能を利用し[a] -> (a -> Bool)ます。Haskell では、これらのオプションは同じであるため、実際には関数を 2 つの引数を受け取り、1 つをとらずに関数を返すかのように書くことができます。

于 2013-10-30T16:09:17.880 に答える