2017-03-12 9 views
4

「コレクションでありマップではない」という意味のClojure述語はありますか?非マップコレクション述語?

このような述語は、マップ以外のすべてのコレクションで実行できる操作が多いため、有用です。たとえば、(apply + ...)または(reduce + ...)は、ベクトル、リスト、遅延シーケンス、およびセットで使用できますが、マップでは使用できません。そのようなコンテキストのマップ要素はclojure.lang.MapEntryになります。それは私の知っているものを述語に問題を引き起こすセットとマップです:

  • sequential?はベクトル、リスト、怠惰なシーケンスのために真であるが、それはマップとセットの両方のために偽です。 (seq?は似ていますが、ベクトルの場合は偽です)
  • coll?seqable?は、私が考えることができる他の種類のコレクションと同様に、セットとマップの両方に当てはまります。

もちろん、このような述語を定義することができます。このような:

(defn coll-but-not-map? 
    [xs] 
    (and (coll? xs) 
     (not (map? xs)))) 

またはこのような

(defn sequential-or-set? 
    [xs] 
    (or (sequential? xs) 
     (set? xs))) 

私は同じことを行いclojure.core内蔵(または貢献ライブラリ)述語があるのか​​どうかと思いまして。

この質問はthis onethis oneに関連していますが、その回答では答えられません。 (私の質問が見つからない場合は、それをそのようにマークしてもらえれば幸いです)

+0

なぜあなたの関数がどのようなデータ構造を持っているのか分かりませんか? @ジョシュはあなたの「はい」/「いいえ」という質問に「いいえ」と回答し、役立つアドバイスを提供しました。あなたがやろうとしていることについてもっと文脈がなくても、あなたを助けるのは難しいです。マルチメソッドを試してみませんか? –

+0

@Brandonに質問ありがとうございます。私は葉のノードが数字の非マップのコレクション、または裸の番号のような何かであるマップの地図(地図の(地図の...))の地図に再帰しています。私は数字の各コレクションの統計を計算したいが、裸の数値は計算しない。現在のところ、リーフコレクションはすべてのシーケンスですが、関数をより一般的なものにして、セットを処理するのはなぜですか?また、fl00rの答えに私のコメントを参照してください。 – Mars

答えて

2

この説明に適合するものは何も見つかりませんでした。私は自分の述語関数が明確でシンプルで、あなたのコードに含めるのが簡単だと思います。

おそらく、非常に汎用的でなければならないコードを記述しているかもしれませんが、通常、関数が一貫したデータ型を受け入れて返す場合があります。これが真実でない場合がありますが、通常、関数がすべての取引のジャックになる可能性がある場合は、あまりにも多くのことをしています。

例を使用すると、数字のベクトル、数字のリスト、または数字の集合を追加することが理にかなっています。しかし、数字の地図ですか?多分それがマップに含まれる値でない限り、意味をなさないでしょう。この場合、連続したデータと連想データの両方の追加を処理するコードが単一のコードであるとは妥当ではありません。この関数は、期待される何かを渡す必要があり、何か一貫性のあるものを返さなければなりません。この種のことは、Stuart Sierraのblog postがこの点について一貫性を議論することを思い出させる。これ以上の情報がなければ、私はあなたのユースケースだけを推測していますが、考慮すべきことです。

+0

ありがとうございました。 Brandonとfl00rに対する私のコメントを見てください。 – Mars

+1

2つの回答のうち1つを任意に選択して受け入れます。この後、誰かがポイントを獲得するはずです。 – Mars

3

例えば(+ ...適用)またはベクトル、リスト、怠惰な配列、およびセットで使用することができます(+ ...減らす)、しかしこれはについては何もマップ

ありませんコレクション、私は思う。あなたの場合、一般的なapplyまたはreduceアプリケーションではなく、特に+の機能を持つ問題があります。 (apply + [:a :b :c])は、ここでベクトルを使用していても機能しません。

私の主張は、ドメイン固有の問題を解決しようとしていることです。そのため、Clojure自体には汎用的な解決策がありません。したがって、あなたが考えることができる適切な述語を使用してください。

+0

私はあなたのポイント、fl00rを理解していますが、マップ以外のすべてのコレクションに共通するものがあると思います。マップの要素は常に 'MapEntry'です。他の種類のコレクションには当てはまりません。基本的には、コレクションを - 地図を除いて - 任意に選択されたタイプの要素のセット(または順序が関係ない場合はシーケンス)として扱うことができます。 '+'は単なるイラストであった(Brandonのコメントに対する私のコメントを参照)。私は他のタイプの要素と同じ点を作ることができました。例: 'apply'または' reduce'に渡された要素が文字列であるマップはありません。 – Mars

+0

@Mars私は見る。しかし、やはり "シーケンス"の視点マップはベクトルのリスト( '' MapEntry''ですが、それにもかかわらず)です。あなたのマップ '{:a 1:b 2}'は本質的にリスト '([:a 1]、[:b 2])'でしょうか?私はこのようにマップが異なることに同意しますが、この場合、 'map? '述語は非常に自然で非常に明示的です。 – fl00r

+0

私は同意します。多くの場合、 'map?'で十分です。しかし、非コレクションの場合は '(not(map?x))'が真であるため、マップ以外のコレクションを識別するには結合または論理和が必要です。私は今、この意味を持つインターフェースを言語に追加することができるかどうかについて考えています。私はそれが良い考えだと思うが、それをRHその他に売ることは難しいだろう。 – Mars