Scheme R7RS のパラメータオブジェクトはReaderモナドか?
SchemeのR7RSを読んでます。
R7RSからパラメータオブジェクトなるものが登場しています。(SRFI-39 からあるようです)
(define radix (make-parameter 10 (lambda (x) (if (and (exact-integer? x) (<= 2 x 16)) x (error "invalid radix"))))) (define (f n) (number->string n (radix))) (print (f 12)) ; ⇒ "12" (print (parameterize ((radix 2)) (f 12))) ; ⇒ "1100" (print (f 12)) ; ⇒ "12" (print (parameterize ((radix 0)) (f 12))) ; ⇒ ERROR: invalid radix
要するに文脈によって(radix)の結果が異なる動作になります。
何となくReaderモナドとlocalという関数が似たような感じに見えました。
こんなふうに見える
module Main where import Control.Monad.Reader import Data.Char (intToDigit) import Numeric (showIntAtBase) -- number->string numberToString :: Int -> Int -> String numberToString x rdx = showIntAtBase rdx intToDigit x "" type Parameter = Either String Int radix :: Parameter radix = Right 10 radix' :: Int -> Parameter radix' x | 2 <= x && x <= 16 = Right x | otherwise = Left "invalid radix" --(define (f n) (number->string n (radix))) f :: Int -> Reader Parameter (Either String String) f n = do rdx <- ask return $ numberToString n <$> rdx main :: IO () main = do print $ runReader (f 12) radix -- Right "12" print $ runReader (local (const $ radix' 2) (f 12)) radix -- Right "1100" print $ runReader (f 12) radix -- Right "12" print $ runReader (local (const $ radix' 0) (f 12)) radix -- Left "invalid radix"
完全に理解できてないのでここまでです。