11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PureScriptで湯婆婆を実装してみる

Posted at

いつの間にか 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 <> "!!"

実行結果

image.png

解説

main

mainに関しては見たままです。 PureScript の知識がなくてもなんとなく分かると思います。 PureScript では関数は引数をカッコで囲んで与える必要はなく, 隣に書くだけで OK です。 間に挟まっている$は関数適用演算子で, a $ b $ c $ da(b(c(d)))に等価です。 全体をカッコで囲う必要がないので便利です。

非 Haskeller に説明が必要そうな部分として, let hoge = ...hoge <- ...の違いは, 右辺がEffectつまり作用を持っているかどうかです。

作用のない, 直の値なら=でそのまま束縛します。

作用を持つなら値そのものではなく, 「それによって得られる値をこのように操作する」という手順(アクション)として記憶します。 そのために使うのが<-です。

logは標準出力にStringを流します。 <>は文字列の結合に使う演算子です。 関数適用は演算子よりも優先度が高いので, 全体をカッコで囲む……かわりに$演算子を使っています。

yubaba

yubabaは気持ち的にはStringをとってStringを返す関数です。 湯婆婆関数とかいうパワーワード。 しかし, 乱数によって結果が変わる……すなわち作用を持つので, 文字列そのものではなく「Stringを得る手段(アクション)」Effect Stringを返します。

lengthStringの文字数Intを返します。

randomIntは第一引数Int以上第二引数Int以下の整数を得ます……が, 乱数なので作用を持ちます。 つまりこの関数はIntそのものではなく「Intを得る手段(アクション)」Effect Intを返しています。 よって<-です。

charAtは第二引数のStringの第一引数Int文字目のCharを返します。

singletonCharStringに変換しています。

pureは少し説明が難しいのですが, 「この値を手順(アクション)Effect Tとして扱う」というような意味を持ちます。 この関数は手順(アクション)を返すからです。 indexは具体的な値そのものではなく, 便宜上つけられた識別名でしかありませんので, 最後に手順(アクション)を返さなければいけないのはそれは当然だよね。

クラッシュする湯婆婆

もちろん元ネタ様にしたがい, 空文字列を与えるとクラッシュします。 やったぜ。

image.png

これはわざと「安全でない」charAtを使用しているためです。 よく見るとUnsafeって書いてあるよね。 PureScript は超・安全志向言語なのでちゃんとしたプログラムではこんなことは起こりませんが, それについて長々と語ってもただの宣伝になってしまいますし, なにより Ja 婆婆らしさ(?)がなくなってしまいますので割愛。

11
4
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
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?