いつの間にか Ja 婆婆が妙に流行っていたのでどれいっちょ Rust で実装してみっかと思って念の為検索をかけたらもういたので, 人気がなさそうなまず間違いなくかぶらない PureScript で実装することにしました。
なお, PureScript で標準入力を実現するのは少し面倒なので, コードに直書きすることにしてます。 すまねえ。 やり方はこちら。
でも代わりに Try PureScript! に貼り付けて実行できるので環境構築とかしなくても遊べるよ。
コード
module Main where
import Prelude
import Data.String.CodePoints (length)
import Data.String.CodeUnits (singleton)
import Data.String.Unsafe (charAt)
import Effect (Effect)
import Effect.Console (log)
import Effect.Random (randomInt)
yubaba :: String -> Effect String
yubaba name = do
let nameLen = length name
index <- randomInt 0 (nameLen - 1)
pure $ singleton $ charAt index name
main :: Effect Unit
main = do
log "契約書だよ。そこに名前を書きな。"
-- 契約書
let name = "千尋"
log $ "フン。" <> name <> "というのかい。贅沢な名だねぇ。"
newName <- yubaba name
log $ "今からお前の名前は" <> newName <> "だ。いいかい、" <> newName <> "だよ。分かったら返事をするんだ、" <> newName <> "!!"
実行結果
解説
main
main
に関しては見たままです。 PureScript の知識がなくてもなんとなく分かると思います。 PureScript では関数は引数をカッコで囲んで与える必要はなく, 隣に書くだけで OK です。 間に挟まっている$
は関数適用演算子で, a $ b $ c $ d
はa(b(c(d)))
に等価です。 全体をカッコで囲う必要がないので便利です。
非 Haskeller に説明が必要そうな部分として, let hoge = ...
とhoge <- ...
の違いは, 右辺がEffect
つまり作用を持っているかどうかです。
作用のない, 直の値なら=
でそのまま束縛します。
作用を持つなら値そのものではなく, 「それによって得られる値をこのように操作する」という手順(アクション)として記憶します。 そのために使うのが<-
です。
log
は標準出力にString
を流します。 <>
は文字列の結合に使う演算子です。 関数適用は演算子よりも優先度が高いので, 全体をカッコで囲む……かわりに$
演算子を使っています。
yubaba
yubaba
は気持ち的にはString
をとってString
を返す関数です。 湯婆婆関数とかいうパワーワード。 しかし, 乱数によって結果が変わる……すなわち作用を持つので, 文字列そのものではなく「String
を得る手段(アクション)」Effect String
を返します。
length
はString
の文字数Int
を返します。
randomInt
は第一引数Int
以上第二引数Int
以下の整数を得ます……が, 乱数なので作用を持ちます。 つまりこの関数はInt
そのものではなく「Int
を得る手段(アクション)」Effect Int
を返しています。 よって<-
です。
charAt
は第二引数のString
の第一引数Int
文字目のChar
を返します。
singleton
はChar
をString
に変換しています。
pure
は少し説明が難しいのですが, 「この値を手順(アクション)Effect T
として扱う」というような意味を持ちます。 この関数は手順(アクション)を返すからです。 index
は具体的な値そのものではなく, 便宜上つけられた識別名でしかありませんので, 最後に手順(アクション)を返さなければいけないのはそれは当然だよね。
クラッシュする湯婆婆
もちろん元ネタ様にしたがい, 空文字列を与えるとクラッシュします。 やったぜ。
これはわざと「安全でない」charAt
を使用しているためです。 よく見るとUnsafe
って書いてあるよね。 PureScript は超・安全志向言語なのでちゃんとしたプログラムではこんなことは起こりませんが, それについて長々と語ってもただの宣伝になってしまいますし, なにより Ja 婆婆らしさ(?)がなくなってしまいますので割愛。