The one using a proper PRNG is more typical.
The other one is more like the paper intended, I think, which is to literally run a side-effect on
every call to choice (lazy I/O), which is what this does (modulo buffered reads).
| {-# LANGUAGE KindSignatures, BlockArguments #-} | |
| {-# language GADTs, LambdaCase, GeneralizedNewtypeDeriving #-} | |
| import Data.Kind | |
| import Data.Functor.Const | |
| import Control.Monad.Free | |
| import Control.Applicative.Free | |
| import qualified Data.ByteString as S | |
| import qualified Data.ByteString.Char8 as S8 | |
| import Data.Functor.Identity | |
| import Data.ByteString (ByteString) |
| {-# LANGUAGE KindSignatures, BlockArguments #-} | |
| {-# language GADTs, LambdaCase, GeneralizedNewtypeDeriving #-} | |
| import Data.Kind | |
| import Data.Coerce | |
| import Data.Functor.Const | |
| import Control.Monad.Free | |
| import Control.Applicative.Free | |
| import qualified Data.ByteString as S | |
| import qualified Data.ByteString.Char8 as S8 | |
| import Data.Functor.Identity |
| {-# LANGUAGE KindSignatures, BlockArguments #-} | |
| {-# language GADTs, LambdaCase, GeneralizedNewtypeDeriving #-} | |
| import Control.Monad.Free | |
| import Control.Applicative.Free | |
| import qualified Data.ByteString as S | |
| import qualified Data.ByteString.Char8 as S8 | |
| import Data.Functor.Identity | |
| import Data.ByteString (ByteString) | |
| import qualified Data.Map as Map | |
| import Data.Map (Map) |
| {-# LANGUAGE KindSignatures #-} | |
| {-# language GADTs, LambdaCase, GeneralizedNewtypeDeriving #-} | |
| import Control.Monad.Free | |
| import Control.Applicative.Free | |
| import qualified Data.ByteString as S | |
| import qualified Data.ByteString.Char8 as S8 | |
| import Data.Functor.Identity | |
| import Data.ByteString (ByteString) | |
| import qualified Data.Map as Map | |
| import Data.Map (Map) |
| -- needs to be a `M i o a', but almost there. LH is difficult (bad docs, bad errors, changing syntax) | |
| {-# LANGUAGE GADTs #-} | |
| {-# OPTIONS_GHC -fplugin=LiquidHaskell #-} | |
| {-# language GeneralizedNewtypeDeriving, DeriveFunctor #-} | |
| {-@ LIQUID "--prune-unsorted" @-} | |
| import Control.Monad.State | |
| import Data.Set qualified as Set |
| {-# OPTIONS_GHC -fplugin=LiquidHaskell #-} | |
| {-# language OverloadedStrings, BangPatterns #-} | |
| import Data.Word | |
| import Foreign.Ptr | |
| import Foreign.C.Types | |
| import Foreign.Marshal.Alloc | |
| import System.Posix.IO.ByteString | |
| import System.Posix.Types | |
| main :: IO () |
| data Todo = Todo { | |
| id :: Text, | |
| created :: UTCTime, | |
| title :: Text, | |
| description :: Text, | |
| priority :: Int | |
| } | |
| data Command | |
| = Add Main.Todo |
| name: Create Functional Pearl discussion weekly | |
| on: | |
| schedule: | |
| - cron: "0 12 * * 5" # 5 = Friday (12:00 UTC) | |
| workflow_dispatch: | |
| jobs: | |
| create-discussion: | |
| runs-on: ubuntu-latest |
The one using a proper PRNG is more typical.
The other one is more like the paper intended, I think, which is to literally run a side-effect on
every call to choice (lazy I/O), which is what this does (modulo buffered reads).
| data Opts = Opts { | |
| startDate :: Text, | |
| step :: Text | |
| } | |
| options = | |
| (\startDate step -> Main.Opts { startDate, step }) | |
| <$> Options.strOption (Option.long "start-date" <> Option.help "Starting date in 2025-01-24 format.") | |
| <*> Options.strOption (Option.long "step" <> Option.help "How many days to add each line.") |