実例によるPureScript 8 章 - 2

Eff モナドに関するところ。説明と演習では Eff が使われているが、Eff は  deprecated になっており、Effect を使う必要がある。ST も変わっている。以下の記事が参考になった。

1.(やや難しい) もし分母で分子を割り切れないなら throwExceptionを使って例外を投げるように safeDivide関数を書き直してください。

safeDivide2 :: Int -> Int -> Effect Int
safeDivide2 _ 0 = throwException $ error $ "Divided by 0"
safeDivide2 a b = pure (a / b)

テスト

main :: Effect Unit
main = do
  x <- safeDivide2 12 2
  logShow $ x
  y <- catchException printException (safeDivide2 12 0)
  logShow $ y
  where
    printException e = do
      logShow e
      pure 0
6
Error: Divided by 0
    at Module.error (...略)


2. (難しい) PIを推定するには次のような簡単な方法があります。単位正方形内にある多数の N個の点を無作為に選び、内接する円に含まれるものの個数 nを数えます。このとき 4n/Nが円周率 piの概算となります。 forE関数、 Random作用、 ST作用を使って、この方法で円周率 piを推定する関数を書いてください。

import Effect (Effect, forE)
import Effect.Random (randomRange)
import Effect.Ref (modify, new, read)

monteCarloPi :: Effect Number
monteCarloPi = do
  let iter = 100000000
  ref <- new 0.0
  forE 0 iter \_ -> do
    x <- randomRange 0.0 1.0
    y <- randomRange 0.0 1.0
    void $ modify (\s -> if (x * x) + (y * y) > 1.0 then s else s + 1.0) ref
  p <- read ref
  pure (4.0 * p / (toNumber iter))

テスト

$ spago repl
 :
> import Main
> monteCarloPi 
3.14137276

> monteCarloPi 
3.14176996


この記事が気に入ったらサポートをしてみませんか?