Bing AIにHaskellを教わった
本記事について
Bing AIにHaskellについて教わったので備忘録を残す。
Bing AIについて
(2023/3/7時点)
- Bing AIは必要に応じてWebサイトの引用、項目の箇条書き、コード例、絵文字などを駆使して回答する(以下の内容は筆者が脚色しているわけではない)
- Bing AIとの会話はAIの回答6回までに制限されている
- Bing AIには3種類の会話スタイルがあり、今回は「バランス」型AIと会話した
凡例
- 「Bing AIに投げた質問」
-
Bing AIからの回答
-
筆者注
AIとの会話に直接現れるものではないコメント
Bing AIとのやりとり
新しい会話のために脳をリセットしました。今は何についてチャットしますか?
「同じデータ型に対して複数のモナドインスタンスがある例を挙げてください」
こんにちは、これはBingです。😊
モナドインスタンスとは、Haskellにおいて、Monadという型クラスに属する型のことです[1]。例えば、List型やMaybe型、IO型などがモナドインスタンスです[2]。
同じデータ型に対して複数のモナドインスタンスがある例としては、以下のようなものがあります[3]。
- ReaderモナドとStateモナドは、共に関数型をモナドインスタンスにするものです。
- WriterモナドとContモナドは、共にペア型をモナドインスタンスにするものです。
- EitherモナドとValidationモナドは、共にEither型をモナドインスタンスにするものです。
これらの例では、同じデータ型でも異なる振る舞いを持つことができます。
筆者注
言い回しに違和感がある。
モナドインスタンスという語に正確な定義があるのかは定かではないが、
少なくともモナドは元々トリプル(3つ組)と呼ばれており、台となるデータ型と pure
と bind
の3つが揃って初めてモナドインスタンスとなると考えるのが妥当なように思う。
また、Bing AIが挙げている例に疑問が残る。
どういう意図でBing AIがこれらのモナドインスタンスを列挙したのかが分からない。(特に継続モナドの例で何を説明しようとしたのかが不明)
しかし、ここはValidationについて突っ込んで聞いていくことにした。
※引用元が間違った記述をしているわけではない。
「Validationモナドとはなんですか?」
Validationモナドとは、Haskellにおいて、Either型をモナドインスタンスにするものの一つです[4]。Validationモナドは、Eitherモナドと違って、失敗した場合に複数のエラーを累積することができます[5]。例えば、入力チェックなどに使えます[6]。
「Validationモナドはどのようにして複数のエラーを累積するのですか?」
Validationモナドは、エラーを累積するために、Applicative型クラスのインスタンスになっています[7]。Applicative型クラスは、モナド型クラスよりも弱い制約を持つため、複数の計算を並列に実行できます[8]。その結果、失敗した計算の結果もすべて保持できるようになります[7:1]。例えば、以下のコードでは、入力データに対して3つのバリデーションを行い、失敗した場合はエラーメッセージをリストとして返します。
import Data.Either.Validation
validate :: Int -> Validation [String] Int
validate x = validate1 x *> validate2 x *> validate3 x
validate1 :: Int -> Validation [String] Int
validate1 x = if x > 0 then Success x else Failure ["x must be positive"]
validate2 :: Int -> Validation [String] Int
validate2 x = if even x then Success x else Failure ["x must be even"]
validate3 :: Int -> Validation [String] Int
validate3 x = if x < 100 then Success x else Failure ["x must be less than 100"]
このコードを実行すると以下のような結果が得られます。
> validate 42
Success 42
> validate (-1)
Failure ["x must be positive","x must be even"]
> validate 101
Failure ["x must be even","x must be less than 100"]
筆者注
これらのソースコードとその実行例はBing AIが回答したものである。
コードの出典は分からなかった。
Bing AIオリジナルのコードなのだろうか?
「ということはつまり、厳密にいえばValidationモナドが複数のエラーを累積するという言い方は間違いで、正しくはValidationのアプリカティブインスタンスがそうするということではないでしょうか?」
はい、その通りです。Validationモナドという言い方は、Validationがモナド型クラスのインスタンスになっていることを強調するためのもので、実際にはValidationのアプリカティブインスタンスがエラーを累積する機能を提供しています。モナド型クラスとアプリカティブ型クラスの関係については、以下の記事が参考になるかもしれません。
: https://qiita.com/suzuki-hoge/items/5178acebb020bc8a519b
「Validationのモナドインスタンスのbindは何をしますか?」
Validationのモナドインスタンスのbindは、失敗した計算の結果を無視して、次の計算に進みます[9]。つまり、最初に失敗した計算のエラーだけが返されます[9:1]。これは、モナド則を満たさないため、Validationは厳密にはモナドではありません[9:2]。例えば、以下のコードでは、validate1とvalidate2が両方とも失敗する場合でも、validate1のエラーだけが返されます。
import Data.Either.Validation
validate :: Int -> Validation [String] Int
validate x = validate1 x >>= validate2
validate1 :: Int -> Validation [String] Int
validate1 x = if x > 0 then Success x else Failure ["x must be positive"]
validate2 :: Int -> Validation [String] Int
validate2 x = if even x then Success x else Failure ["x must be even"]
このコードを実行すると以下のような結果が得られます。
> validate 42
Success 42
> validate (-1)
Failure ["x must be positive"]
> validate 101
Failure ["x must be even"]
「では正確に言えばValidationモナドという言い方は間違いであるということでしょうか?」
はい、Validationモナドという言い方は、厳密には間違いです。Validationはモナド型クラスのインスタンスになっていますが、モナド則を満たしていません。したがって、Validationは正しくはモナドではなく、アプリカティブファンクターと呼ぶべきです。
筆者注
少なくともHaskellの Validation
はMonadインスタンスを持たないようである。
(>>=)
の代わりに bindValidation
という名前の関数としており、これがモナド則を満たさないことを明示しているようだ。
Bing AIの会話制限に到達してしまったので会話はここで打ち切りとなった。
所感
Bing AIの精度は予想以上に高く、会話が成立しているとすら感じた。
AIの有用性が上がったとは言っても、記述が正しいかどうかを判断するための知識というものは依然として必要なように思う。
ただし、それはライターがAIであろうとも人間であろうとも変わらないことでもある。
物事を表面的にしか理解していないとAIに出し抜かれる恐れは十分にあると感じた。
Discussion