LoginSignup
8
0

More than 3 years have passed since last update.

Haskellにはそもそも+++という演算子が存在する

Posted at

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は、abのどちらかを表す型です。
 すなわち、この関数の型は「bを受け取ってcを返す関数」と「b'を受け取ってc'を返す関数」を結合(+++)させて、「Either b b'を受け取ってEither c c'を返す関数」にすると読めます。
 Either b b'bb'のどちらが入っているか分からないけど、bcにする関数と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では演算子をある程度自由に定義できる。そのため、演算子の解釈に困ることはない。(演算子が何を意味しているのかで悩むことは滅茶苦茶ある)

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0