2016-12-23 9 views
1

パターンマッチングで合計型付き値を分解したくありません。その尖ったスタイルのために、私にとっては外人だと感じています。 私はむしろsum型のために関数switchを書いて使います。GHCを使ったポイントフリーの構造化

私の質問は、一般的に任意の合計の種類についてですが、私は例としてEitherでそれを示しています。この拡張子を持つ

data Processor cl cr r = MakeProcessor { l :: cl -> r, r :: cr -> r } 

switch :: Processor cl cr r -> Either cl cr -> r 
switch p ei = 
    case ei of 
     Left x -> l p x 
     Right x -> r p x 

Eitherへ:これの代わりに

map f e = 
    case e of 
     Left x -> Left x 
     Right x -> Right (f x) 

私はこれを書くことができます:

map f = switch (MakeProcessor { l : Left, r : f >>> Right }) 

私はほとんどの状況でより良い感じ。

このような拡張用のものを書くには、合計タイプの機械作業である[Processorswitch]。ですから、私はコンパイラ[GHC]を私のためにやる方法があるのだろうか?無意味な型で合計型の値を削除する方法はありますか?


注:例としてEitherを使用しました。 Eitherは間違った選択でした。多くの読者が私の質問は約Eitherだったと思っていたので、私はeitherと指摘しました。

switch p ei = either (l p) (r p) ei 

:私はeither機能を使用すると、Either a b値にLeftRight値に適用するために別々の機能を指定できます

data Result a b = Fail a | Success b 
+0

「レンズ」ライブラリが役立つ場合があります。 'map'関数を' over _Right'として書くことができます。 –

+0

私は_RightがTemplateHaskellから来ると思いますよね?たぶんこれは厳しいですが、SafeHaskellと互換性がないため、私はTHを避けていました。 – libeako

+0

私の「どちらかの」例は、パターンマッチングを避ける私の方法の単なる例です。これは、ベースライブラリ内の 'どちらか 'の関数のより安全なバージョンです。私の質問は特に「どちらか」に関するものではなく、例としてのみ使用します。 – libeako

答えて

2

短い答えはノー(特にTemplate Haskellなし)です。

しかし、関数型プログラミングの多くの構造体のように、逆さまにすることができます。 Church/Scottエンコーディングを使用します(データ型が再帰的でない場合も同じです)。それは型の定義だから

newtype ChurchEither a b = ChurchEither { switch :: forall c. (a -> c) -> (b -> c) -> c } 

とは、あなたが自由のためのエリミネーターswitchを得るが、あなたが本当に何を得ていない自分自身そう

left x = ChurchEither (\l r -> l x) 
right x = ChurchEither (\l r -> r x) 

コンストラクタを記述する必要がboilerplate-賢い。

+0

私はあなたの最初の行を私の質問に対する答えと考えています。 – libeako

4

などの基本ライブラリにない和タイプを、使用している必要がありますすぐに両方の側からeiを落として

switch p = either (l p) (r p) 

pをドロップする機能のためのApplicativeインスタンスを使用することができます。

switch = either <$> l <*> r 

任意和タイプについては、次の方法で包まれた値を減少させeitherのような機能のために派手な名前である適切なcatamorphismを、提供する必要がありますラップされた型への合計型。

+0

私の「どちらかの」例は、パターンマッチングを避ける私の方法の単なる例です。これは、ベースライブラリ内の 'どちらか 'の関数のより安全なバージョンです。私の質問は特に「どちらか」に関するものではなく、例としてのみ使用します。 – libeako

+1

あなたの方法が「どちらか」よりも安全であるという意味を説明できますか? –

+0

安全性: コードミスの可能性は、「どちらか」のパラメータの順序を反転することです。 'Either'に格納された値の型が等しい場合、型付きエラーはありません。 「どちらか」は、この種の間違いの可能性を実証するための悪い例ですが、私は一般的に、他の合計型に対して危険が現実だと思います。したがって、私はむしろプロセッサ関数をレコードに入れて、名前を付けることができます。 – libeako

関連する問題