-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
type inference with OverloadedRecordDot #21
Comments
Interesting! This appears to be an awkward interaction between how GHC desugars record dot and the incoherent instances that Bluefin uses to encode its set index types. I simplified it to an example not involving record dot. I don't have any immediate plans to address this, because I'm skeptical that the situation can be improved, unfortunately. Thank you for the report and please do file any other issues you come across, and feel free to ask any questions. {-# LANGUAGE GHC2021 #-}
{-# LANGUAGE OverloadedRecordDot #-}
import Bluefin.Eff
import Bluefin.Compound
import Bluefin.State
import Prelude
data Env e = MkEnv {stateA :: State Int e}
runEnv
:: Int
-> (forall e. Env e -> Eff (e :& es) r)
-> Eff es r
runEnv a action =
evalState a $ \sA -> do
useImplIn action MkEnv{stateA = mapHandle sA}
run :: ()
run = runPureEff $ do
runEnv 1 $ \(env :: Env e') -> do
-- Just a convenient way of getting es into scope
(_ :: Eff es ()) <-
let nested :: Eff es (Eff es ())
nested = pure (pure ())
in nested
-- This is fine.
_ <- get (stateA env)
-- This is fine.
_ <- get @e' (stateAClass env)
-- This is fine.
_ <- get @e' (env.stateA)
-- These don't work
_ <- get @e' @(e' :& es) (stateAClass env)
_ <- get @_ @(e' :& es) (stateAClass env)
_ <- get (stateAClass env)
pure ()
class r ~ Env e => IsEnv e r
instance r ~ Env e => IsEnv e r
stateAClass :: IsEnv e r => r -> State Int e
stateAClass = stateA |
I'm fine with this solution. run :: ()
run = runPureEff $ do
runEnv 1 $ \(env :: Env e') -> do
_ <- get @e' (env.stateA) Most likely, I'd still pass run = runPureEff $ do
runEnv 1 $ \(env :: Env e') -> do
res <- doImportantStuff env
s <- get @e' env.something --inspect env
return (res, s) In which case, maybe it is worth documenting somewhere. I'm fine with closing this issue, but I'll leave it up to you. |
Great!
Yeah, it does, but remember you can use
Do you mean documenting the solution that uses
Let's leave it open for a bit, at least until I've put something in the documentation. |
You should rename it to
There is a There is another tip I'd add, passing effects as values works really well with funcWithEff eff = \cases
True -> ...
False -> ... |
😂 Do you mean you're starting to write C in Haskell?
Great!
Yes, I see. I'll have to think how to explain this one and where it should be placed, so that it's helpful but doesn't cause additional confusion by simply existing.
Oh, interesting, do you have a more fleshed out example you can provide, so I can see what this looks like in a real usage? |
I went full circle. Thanks, I guess.
The major complaint I see about The Handle Pattern is passing those handles around. But for me, it is pattern matching. data Exp
= Number Int
| Add Exp Exp
| Subtract Exp Exp
| Multiply Exp Exp
| Divide Exp Exp
deriving (Show)
eval :: Exp -> Int
eval (Number i) = undefined
eval (Add e1 e2) = undefined
eval (Subtract e1 e2) = undefined
eval (Multiply e1 e2) = undefined
eval (Divide e1 e2) = undefined So far so good, let's add some state. evalS :: (e :> es) => State Int e -> Exp -> Eff es Int
evalS s (Number i) = undefined
evalS s (Add e1 e2) = undefined
evalS s (Subtract e1 e2) = undefined
evalS s (Multiply e1 e2) = undefined
evalS s (Divide e1 e2) = undefined How about exceptions? evalSE
:: (e1 :> es, e2 :> es)
=> State Int e1
-> Exception SomeException e2
-> Exp
-> Eff es Int
evalSE s ex (Number i) = undefined
evalSE s ex (Add e1 e2) = undefined
evalSE s ex (Subtract e1 e2) = undefined
evalSE s ex (Multiply e1 e2) = undefined
evalSE s ex (Divide e1 e2) = undefined So now I have those But evalSE'
:: (e1 :> es, e2 :> es)
=> State Int e1
-> Exception SomeException e2
-> Exp
-> Eff es Int
evalSE' s ex = \cases
(Number i) -> undefined
(Add e1 e2) -> undefined
(Subtract e1 e2) -> undefined
(Multiply e1 e2) -> undefined
(Divide e1 e2) -> undefined
-- With multiple params too.
evalSE''
:: (e1 :> es, e2 :> es)
=> State Int e1
-> Exception SomeException e2
-> Exp
-> Int
-> Eff es Int
evalSE'' s ex = \cases
(Number i) n -> undefined
(Add e1 e2) n -> undefined
(Subtract e1 e2) n -> undefined
(Multiply e1 e2) n -> undefined
(Divide e1 e2) n -> undefined It is not strictly the same, because I can't hide This code of mine is probably ugly and dysfunctional enough to be considered real world. Bonus: I just learned this about f :: Int -> Int -> Int -> Int
f _ = \cases
_ -> id |
Hello. Just finished porting my little lib to Bluefin and so far I like it. So thanks!
I did encounter this behavior, but I am not sure what to do about it. I'm on GHC 9.6.6.
It is a minor annoyance, but, I guess, worth reporting.
The text was updated successfully, but these errors were encountered: