packages feed

polysemy-0.5.0.0: bench/Poly.hs

{-# LANGUAGE DataKinds        #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs            #-}
{-# LANGUAGE TemplateHaskell  #-}
{-# LANGUAGE TypeApplications #-}

{-# OPTIONS_GHC -fwarn-all-missed-specializations #-}

module Poly where

import Polysemy
import Polysemy.Error
import Polysemy.Resource
import Polysemy.State
import Polysemy.Input
import Polysemy.Output


slowBeforeSpecialization :: Member (State Int) r => Sem r Int
slowBeforeSpecialization = do
  n <- get
  if n <= 0
     then pure n
     else do
       put $ n - 1
       slowBeforeSpecialization

{-# SPECIALIZE slowBeforeSpecialization :: Sem '[State Int] Int #-}


countDown :: Int -> Int
countDown s =
  fst . run . runState s $ slowBeforeSpecialization

prog
    :: Sem '[ State Bool
            , Error Bool
            , Resource
            , Lift IO
            ] Bool
prog = catch @Bool (throw True) (pure . not)

zoinks :: IO (Either Bool Bool)
zoinks = fmap (fmap snd)
       . (runM .@ runResourceInIO .@@ runErrorInIO)
       . runState False
       $ prog

data Console m a where
  ReadLine :: Console m String
  WriteLine :: String -> Console m ()

makeSem ''Console

runConsoleBoring :: [String] -> Sem (Console ': r) a -> Sem r ([String], a)
runConsoleBoring inputs
  = runFoldMapOutput (:[])
  . runListInput inputs
  . reinterpret2
  (\case
      ReadLine -> maybe "" id <$> input
      WriteLine msg -> output msg
  )