Help us understand the problem. What is going on with this article?

fixで簡単にループを書く

More than 1 year has passed since last update.

fixは関数の最小不動点を求める関数です。

fix :: (a -> a) -> a
fix f = f (fix f)

例えば

> fix (const "hello")
"hello"

常に文字列"hello"を返す関数の不動点(入力と出力が同じになる値)は"hello"です。(参考: Haskell/不動点と再帰)

fixといえば無名関数で再帰を書く時に使われる例が有名だと思います

fact :: Int -> Int
fact = fix $ \f n -> if n == 0 then 1 else n * f (n-1)

再帰関数が最小不動点として構成できるというのは凄いですね。(参考: 再帰プログラムの意味論について)

fixで簡単にループを書く

fixは普段コードを書くときも便利に使えます。例えばユーザーからの入力を反転して出力する動作を"quit"という入力が来るまで繰り返すプログラムを考えましょう

import Control.Monad
import Data.Function

main :: IO ()
main = do
    putStrLn "Start"
    fix $ \loop -> do               -- ループ開始
        str <- getLine              -- 入力待ち
        unless (str == "quit") $ do -- "quit"じゃ無ければ次を実行
            putStrLn (reverse str)  -- 反転して表示
            loop                    -- 繰り返し
    putStrLn "Bye"

fixを使わない場合letを使って再帰関数を一旦定義してから実行するといった手順でもできますが、fixを使ったほうが定義と実行が一度にできるのでスッキリすると思います。好みの問題かもしれませんが :expressionless:

ループに初期値を与える

次に先ほどのプログラムに回数制限を設けてみます。"quit"と入力されなくても3回ループすると自動的に終わるようにしてみます。

import Control.Monad
import Data.Function

main :: IO ()
main = do
    putStrLn "Start"
    ($ 3) . fix $ \loop n -> do         -- 初期値に3を与えてループ開始
        unless (n == 0) $ do            -- nが0じゃ無ければ次を実行
            str <- getLine              -- 入力待ち
            unless (str == "quit") $ do -- "quit"かどうか確認
                putStrLn (reverse str)  -- 反転して表示
                loop (n-1)              -- nを1減らして繰り返す
    putStrLn "Bye"

$を使ってfixで作った関数に値を適用しています。

fixだよ!!!

無名関数で再帰するjavascript

lotz
実用関数型プログラミング言語 Haskell の情報を発信しています
http://lotz84.github.io/
folio-sec
誰もがかんたんに資産運用することができるサービス「フォリオ」を作っているFinTech系スタートアップ
https://corp.folio-sec.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした