Haskellにはそもそも+++という演算子が存在する
JavaScriptで+++は許されない+ ++は許される を読んで書きましたシリーズです。
+++演算子の説明
Haskellには、+++
は許される/許されない以前に、まさにそのような演算子が存在します。
これはControl.Arrow
モジュールで定義されているArrowChoice
型クラスのメソッドであり、次のような型を持つ演算子です。
(+++) :: ArrowChoice a => a b c -> a b' c' -> a (Either b b') (Either c c')
慣れていなければ読みづらいので、少しこれに説明をつけます。
最も一般的なArrowChoice
型クラスのインスタンスは単純な関数なので、簡単にするためにa
をこれに置き換えます。
(+++) :: (b -> c) -> (b' -> c') -> (Either b b') -> (Either c c')
Either a b
は、a
かb
のどちらかを表す型です。
すなわち、この関数の型は「b
を受け取ってc
を返す関数」と「b'
を受け取ってc'
を返す関数」を結合(+++
)させて、「Either b b'
を受け取ってEither c c'
を返す関数」にすると読めます。
Either b b'
はb
かb'
のどちらが入っているか分からないけど、b
をc
にする関数とb'
をc'
にする関数の両方があれば適切な方の関数を適用することができるという理屈ですね。
&&&演算子もある
こちらも+++
同様Control.Arrow
モジュールで定義されています。ポインタや論理積とは全く関係ありません。
(&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
Haskellでは好きな演算子を定義できる!!
ところで、Haskellでは、かなり高い自由度で自分の好きな二項演算子を定義することができます。
普通の足し算に物足りなくなったら、++++++++++
演算子を定義してパーティー気分を味わいましょう。
(++++++++++) :: Int -> Int -> Int
a ++++++++++ b = a + b
C++のあの演算子を真似すれば、謎のプロっぽさが出るかもしれません。
a .* mp = undefined
p ->* mp = undefined
他にも、カッコいい矢印を使ってFizzBuzzを書いてみたりできます。
(~>) :: Int -> String -> Int -> Maybe String
a ~> s = \b -> s <$ guard (b `mod` a == 0)
fizzbuzz :: Int -> String
fizzbuzz = fromMaybe . show <*> (3 ~> "fizz" <> 5 ~> "buzz" )
矢印->
が予約されていることへの反抗として、クソ長矢印を定義してもいいでしょう。なんかコメントっぽくハイライトされていますが、これは合法なHaskellコードです。
a ----------> b = undefind
まとめ
Haskellには、+++
という演算子が存在する。
Haskellでは演算子をある程度自由に定義できる。そのため、演算子の解釈に困ることはない。(演算子が何を意味しているのかで悩むことは滅茶苦茶ある)