6

私はJSからライブラリを移植しようとしていますが、文字列または文字列のリストを取ることができる関数になっています。文字列が与えられた場合、それは文字列のリストに分割され、最初にその文字列が渡されたかのように処理されます。関数をElmで複数の型にすることはできますか?オーバーロードされた機能を使用できますか?

自分のタイプを定義することで並べ替えることができますが、APIが醜いものになり、カスタムタイプのプレフィックスが必要になります。

type DocumentBody = Raw String | Words List String 

tokenize: DocumentBody -> List String 
tokenize s = 
    case s of 
     Raw str_body -> String.split " " str_body |> (List.map String.toLower) 
     Words list_body -> List.map String.toLower list_body 

-- Tests 

tests = 
    suite "Tokenizer" 
    [ test "simple" <| assertEqual ["this", "is", "a", "simple", "string"] 
            <| tokenize (Raw "this is a simple string") 

    , test "downcasing tokens: string" <| assertEqual ["foo", "bar"] 
                 <| tokenize (Raw "FOO BAR") 

    , test "downcasing tokens: list of str" <| assertEqual ["foo", "bar"] 
                  <| tokenize (Words ["Foo", "BAR"]) 
    ] 

最終的に、私はポートが行動のこの種をサポートしなければならないということはないと思うが、どのようにタイプの単なる列挙であなたパターンマッチを行う代わりに:ここで

は、私が持っているものです私の例ではプレフィックスRawまたはWordsが必要ですか?

答えて

4

いいえ、あなたは他の言語と同じ方法でelmの関数をオーバーロードできません。各関数には単一の署名があります。関数が多くの型の可能性のあるパラメータを受け入れるようにするには、union型を使用するソリューションがうまくいきます。

あなたは、APIが醜いと言います。私はそれを醜いと呼ぶつもりはない。おそらく、型宣言やcase文の構文は魅力的ではありませんが、私は時間を与えています。それはあなたの上に成長します。そこには多くの力と安全性があります。あなたはコードに何らかの前提を付けさせず、すべてのシナリオを処理しなければならず、それはelmのような言語で作業する強みの1つです。

パターンマッチングコードが適切です。あなたはそれを超えてそれを短縮することはできません。

同時に、私はJavaScriptライブラリを書き直し、生のJavaScriptからポートを介して通信しようとすると、苦労することが分かります。はるかに厳格な言語で物事を書き直しているので、javascriptで何かと何かを受け入れた関数の署名を複製することはできません。しかし、やはりこれはニームの強みであり、弱さではありません。この機会を利用してAPIを強化し、あいまい性を除去します。

具体的な例を考えてみると、解決策を超えていくつかの選択肢があるように感じられます。私は、tokenize関数があまりにも有望であると主張したいと思います。あまりにもあいまいです。関数型言語でコードを書くときは、物を小さくして構成可能なものにすることを好みます。私にとっては、本当に2つの別々の機能でなければなりません。

+0

"...あなたは関数の署名を複製することはできません..."またはむしろそれらの完全な欠落を複製します;) –

+0

あなたのポイントに、呼び出し側は 'DocumentBody'が何であるか知る必要があります。それはこの関数がとるタイプなので、 'Raw'と' Words'タイプのプレフィックスを公開するのは意味があります。 –

+0

これはポートではっきりと行われたものではないので、私はそれを別々の機能。 –

関連する問題