HFMU / HaskellFmu

The library package to include in order to develop an FMU with Haskell
Other
1 stars 0 forks source link

IO Refactoring #14

Open CThuleHansen opened 5 years ago

CThuleHansen commented 5 years ago
--Before 
firstFunction :: (StablePtr (IORef (FMIT.FMIComponent a))) -> (FMIT.FMIComponent a -> W.Writer [T.LogEntry] (FMIT.FMIComponent a, T.Status)) -> IO CInt
firstFunction comp f =
  let g state =
        let (stateStatus, entries) = W.runWriter $ f state
        in
          firstFunctionWriteState comp stateStatus
  in
    firstFunctionPoly comp g

firstFunctionIO :: (StablePtr (IORef (FMIT.FMIComponent a))) -> (FMIT.FMIComponent a -> IO (W.Writer [T.LogEntry] (FMIT.FMIComponent a, T.Status))) -> IO CInt
firstFunctionIO comp f =
  let g state = do
        stateStatus :: W.Writer [T.LogEntry] (FMIT.FMIComponent a, T.Status) <- f state
        let (stateStatus', entries) = W.runWriter stateStatus
          in
          firstFunctionWriteState comp stateStatus'
  in
    firstFunctionPoly comp g

firstFunctionPoly :: (StablePtr (IORef (FMIT.FMIComponent a))) -> (FMIT.FMIComponent a  -> IO CInt) -> IO CInt
firstFunctionPoly comp f = do
  state <- getStateImpure comp
  f state

firstFunctionWriteState :: (StablePtr (IORef (FMIT.FMIComponent a))) -> (FMIT.FMIComponent a, T.Status) -> IO CInt
firstFunctionWriteState comp (state, status) = writeState comp state >> (pure . FMIT.statusToCInt) status
--After
firstFunction :: (StablePtr (IORef (FMIT.FMIComponent a))) -> (FMIT.FMIComponent a -> W.Writer [T.LogEntry] (FMIT.FMIComponent a, T.Status)) -> IO CInt
firstFunction comp f =
  firstFunctionIO comp $ return . f

firstFunctionIO :: (StablePtr (IORef (FMIT.FMIComponent a))) -> (FMIT.FMIComponent a -> IO (W.Writer [T.LogEntry] (FMIT.FMIComponent a, T.Status))) -> IO CInt
firstFunctionIO comp f = do
  state <- getStateImpure comp
  w <- f state
  firstFunctionWriteState comp $ fst . W.runWriter $ w

firstFunctionWriteState :: (StablePtr (IORef (FMIT.FMIComponent a))) -> (FMIT.FMIComponent a, T.Status) -> IO CInt
firstFunctionWriteState comp (state, status) = writeState comp state >> (pure . FMIT.statusToCInt) status
CThuleHansen commented 5 years ago
trcc
Is it bad practise to lift something into IO that is not IO?
vk3wtf has joined (~doc@2a07-a880-4601-1031-f9ca-19a3-5376-13e9.pool6.ovpn.com)
tdammers
define "lift into IO"
trcc
hehe ye, I was thinking htat myself
sQVe has left IRC (Quit: Bye!)
sQVe has joined (~sQVe@unaffiliated/sqve)
tdammers
normally, "lifting" refers to taking a value of some type t, and converting that into a value of a type that is based on t, typically in a monad transformer situation
tdammers
e.g., suppose you have type MyStack = StateT Foo IO, then you can "lift" a value of type IO Int to MyStack Int
tdammers
:t lift
lambdabot
(Monad m, MonadTrans t) => m a -> t m a
DrLambda has left IRC (Ping timeout: 272 seconds)
tdammers
:t liftIO
lambdabot
MonadIO m => IO a -> m a
trcc
I have a function a -> (b -> IO c) -> d and a function a -> (b -> c) -> d. I need to do some of the same stuff, so therefore I would like to wrap these. But it is difficult, since one has to deal with IO c, whereas the other does not. Therefore I currently have two functions
chele has joined (~chele@2a02:8106:1:f900:faca:b8ff:fe2f:8499)
trcc
so I am thinking of taking the second function, b->c and lifting it into (b -> IO c)
tdammers
the former function cannot apply its second argument anyway, so those types don't make a lot of sense
trcc
sorry, b should be a
tdammers
unless you have a MonadIO constraint on d
trcc
og a should be d heh
trcc
b*
tdammers
no, that's not the problem
trcc
a -> (a -> IO c) -> d and a function a -> (a -> c) -> d
mounty has left IRC (Ping timeout: 258 seconds)
tdammers
it cannot apply the (b -> IO c) argument, because there is nothing you can do with the resulting IO value except ignore it
trcc
a -> (a -> IO c) -> IO d and a function a -> (a -> c) -> IO d
trcc
there you go
trcc
sorry
tdammers
right
tdammers
that makes more sense
tdammers
so let's fix the rest
tdammers
say you have:
tdammers
fIO :: a -> (a -> IO c) -> IO c
mounty has joined (~mounty@n106-71-211-213.rdl2.qld.optusnet.com.au)
tdammers
fPure :: a -> (a -> c) -> IO c
danvet has joined (~Daniel@2a02:168:569e:0:3106:d637:d723:e855)
matheus23 has joined (~matheus23@2a02:8071:328f:6c00:daa6:1d22:c9c:fdfe)
tdammers
and you want to express fPure in terms of fIO
tdammers
does that sound about right?
trcc
let me think
kadoban has left IRC (Quit: bye)
trcc
I think so yes
tdammers
OK
tdammers
so all you need, really, is a way of getting from (a -> c) to (a -> IO c)
trcc
which does not seem too bad. Let me try for a sec
ziyourenxiang has left IRC (Ping timeout: 246 seconds)
tdammers
:t return -- this is going to help
lambdabot
Monad m => a -> m a
samurdha has joined (~samurdha@dyn-209-2-221-210.dyn.columbia.edu)
tdammers
:t pure -- or this, same thing really
lambdabot
Applicative f => a -> f a
tito_04 has left IRC (Remote host closed the connection)
taurux has joined (~tito@gateway/tor-sasl/tito04/x-53358538)
crobbins_ has joined (~crobbins@198.11.8.226)
carif has joined (~mcarifio@cpe-67-246-228-200.rochester.res.rr.com)
crobbins has left IRC (Ping timeout: 250 seconds)
gxt has left IRC (Ping timeout: 252 seconds)
revprez_anzio has left IRC (Read error: Connection reset by peer)
DrAwesomeCraws has left IRC (Remote host closed the connection)
revprez_anzio has joined (~revprez_a@static-173-76-190-156.bstnma.ftas.verizon.net)
DrAwesomeCraws has joined (~DrAwesome@c-75-68-71-41.hsd1.ct.comcast.net)
dmiles has left IRC (Read error: Connection reset by peer)
nowhere_man has left IRC (Ping timeout: 258 seconds)
trcc
tdammers: That just about removed 10 lines of code and made it much easier to understand: https://github.com/HFMU/HaskellFmu/blob/master/src/HaskellFMU.hs#L29-L37 Thank you for you help. I go into this mind-mess where I thought it was bad to lift to IO, when it was a pure function originally. But I am doing it in the next step anyways
hexfive has joined (~hexfive@50-47-134-163.evrt.wa.frontiernet.net)
ByronJohnson has left IRC (Ping timeout: 257 seconds)
toovs has left IRC (Ping timeout: 258 seconds)
ByronJohnson has joined (~bairyn@unaffiliated/bob0)
trcc
tdammers: to compare: https://gist.github.com/CThuleHansen/ca19a563870e0af1567b7873fa5f4fd4 :D
Jesin has left IRC (Ping timeout: 257 seconds)
dmiles has joined (dmiles@c-73-190-111-74.hsd1.wa.comcast.net)
toovs has joined (~toovs@c-98-238-150-172.hsd1.ca.comcast.net)
carif has left IRC (Ping timeout: 272 seconds)
Jesin has joined (~Jesin@pool-72-83-62-150.washdc.fios.verizon.net)
dnlkrgr has joined (~dnlkrgr@200116b82ba56e0041674e3155352d71.dip.versatel-1u1.de)
tdammers
this is absolutely fine
tdammers
going the other way around is what you shouldn't be doing
09:19 tdammers
i.e., run IO actions upon evaluating non-IO expressions, via the unsafePerformIO backdoor
ogradyda has joined (~ogradyda@monad.Informatik.Uni-Tuebingen.De)
kadoban- is now known as mud
darjeeling_ has left IRC (Ping timeout: 250 seconds)
trcc
great thanks