Skip to content

Instantly share code, notes, and snippets.

@BenSchZA
Created November 12, 2020 08:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BenSchZA/57f1f46ec8e2ecc0f304ede813e5f4eb to your computer and use it in GitHub Desktop.
Save BenSchZA/57f1f46ec8e2ecc0f304ede813e5f4eb to your computer and use it in GitHub Desktop.
{-# LANGUAGE Arrows #-}
{-# LANGUAGE BlockArguments #-}
module Main where
import Control.Concurrent
import FRP.Yampa
data State = State { value :: Double } deriving (Show)
initialState = State 25.0
cooling :: State -> SF () (State)
cooling state = (constant (-1) >>> integral) >>^ (+ value state) >>> arr (State)
coolingWithFloor :: State -> SF () (State)
coolingWithFloor state = switch cooling' atRoomTemp
where t' = cooling state
cooling' = ((arr (\_ -> t')) &&& ((\_ -> t') ^>> value ^>> (<= 18) ^>> edge >>^ (\e -> e `tag` t')))
atRoomTemp _ = (constant 18)
main :: IO ()
main = reactimate (return ())
(\_ -> threadDelay 1 >> return (0.1, Nothing))
(\_ b -> (putStrLn $ show b) >> return False)
(coolingWithFloor initialState)
@BenSchZA
Copy link
Author

scratchpad/Main.hs:16:26: error:
     Couldn't match type SF () State with State
      Expected type: SF () State
        Actual type: SF () (SF () State)
     In the expression: switch cooling' atRoomTemp
      In an equation for coolingWithFloor’:
          coolingWithFloor state
            = switch cooling' atRoomTemp
            where
                t' = cooling state
                cooling'
                  = ((arr (\ _ -> t'))
                       &&&
                         ((\ _ -> t')
                            ^>> value ^>> (<= 18) ^>> edge >>^ (\ e -> e `tag` t')))
                atRoomTemp _ = (constant 18)
   |
16 | coolingWithFloor state = switch cooling' atRoomTemp
   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^

scratchpad/Main.hs:18:60: error:
     Couldn't match type State with SF () State
      Expected type: SF (SF () State) (Event (SF () State))
        Actual type: SF State (Event (SF () State))
     In the second argument of (^>>), namely
        value ^>> (<= 18) ^>> edge >>^ (\ e -> e `tag` t')
      In the second argument of (&&&), namely
        ((\ _ -> t')
            ^>> value ^>> (<= 18) ^>> edge >>^ (\ e -> e `tag` t'))
      In the expression:
        ((arr (\ _ -> t'))
           &&&
             ((\ _ -> t')
                ^>> value ^>> (<= 18) ^>> edge >>^ (\ e -> e `tag` t')))
   |
18 |           cooling' = ((arr (\_ -> t')) &&& ((\_ -> t') ^>> value ^>> (<= 18) ^>> edge >>^ (\e -> e `tag` t')))        
   |                   

@BenSchZA
Copy link
Author

Original code:

cooling :: Double -> SF () (Double)
cooling t0 = proc input -> do
               t0' <- integral >>^ (+ t0) -< -1
               returnA -< t0'

coolingWithFloor :: Double -> SF () (Double)
coolingWithFloor t0 = switch cooling' atRoomTemp
    where cooling' = proc _ -> do
                        t' <- cooling t0 -< ()
                        e <- edge -< t' <= 18
                        returnA -< (t', e `tag` t')
          atRoomTemp _ = (constant 18)

main :: IO ()
main = reactimate (return ())
                (\_ -> threadDelay 100000 >> return (0.1, Nothing))
                (\_ b -> (putStrLn $ show b) >> return False)
                (coolingWithFloor 25.0)

@BenSchZA
Copy link
Author

The solution!

{-# LANGUAGE Arrows         #-}
{-# LANGUAGE BlockArguments #-}

module Main where

import           Control.Concurrent
import           FRP.Yampa

data State = State { value :: Double } deriving (Show)
initialState = State 25.0

cooling :: State -> SF () (State)
cooling state = (constant (-1) >>> integral) >>^ (+ value state) >>^ State

coolingWithFloor :: State -> SF () (State)
coolingWithFloor state = switch cooling' atRoomTemp
    where t' :: SF () State
          t' = cooling state
          branch_a :: SF () State
          branch_a = t'
          branch_b :: SF () (Event (SF () State))
          branch_b = (t' >>> value ^>> (<= 18) ^>> edge >>^ (\e -> e `tag` t'))
          cooling' :: SF () (State, Event (SF () State))
          cooling' = branch_a &&& branch_b
          atRoomTemp :: p -> SF b State
          atRoomTemp = (\_ -> constant 18 >>^ State)

main :: IO ()
main = reactimate (return ())
                (\_ -> threadDelay 100000 >> return (0.1, Nothing))
                (\_ b -> (putStrLn $ show b) >> return False)
                (coolingWithFloor initialState)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment