Skip to content
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

Add evalState (to Control.Functor.Linear) #404

Closed
andreasabel opened this issue Apr 10, 2022 · 5 comments · Fixed by #411
Closed

Add evalState (to Control.Functor.Linear) #404

andreasabel opened this issue Apr 10, 2022 · 5 comments · Fixed by #411

Comments

@andreasabel
Copy link
Contributor

evalState is a common use-case of the state monad.

import Control.Functor.Linear
import Data.Tuple.Linear

evalState :: Consumable s => State s a %1 -> s %1 -> a
evalState m s = fst (runState m s)

Probably there should also be evalStateT.

@aspiwack
Copy link
Member

I'm not sure that evalState is quite as useful as in the case of the unrestricted-state monad. That being said, I'll welcome a PR, but see my thoughts in #405 (comment).

@andreasabel
Copy link
Contributor Author

Maybe I can do without it, but I didn't see how because of the Ur in the type of HashMap.empty. I'd be happy for advice, see my code at: https://gist.github.com/andreasabel/f5c877491d32b653efba44cb283ba490#file-interpretermain-hs

andreasabel added a commit to andreasabel/linear-base that referenced this issue Apr 12, 2022
Replacing response type `Ur b` by simply `b` also checks and enables
uses like
```haskell
let (i, _) = HashMap.empty 100 (\ env -> runState (eval e) env)
```
(see issue tweag#404).

Caveat: I am relying on the linea type checker (which might be in
alpha state, dunno), so there might be reasons unknown to me why this
generalization is invalid.  Test suite passes, though.
@andreasabel
Copy link
Contributor Author

I just tried to generalize the response type of HashMap.empty from Ur b to b and the type checker allowed it:

So if this is an admissible generalization, the need for evalState would be reduced considerably, and one could decide of the fate of the final state later. As it stands (without #410), one seems to have to consume the final state in the continuation passed to HashMap.empty already.

@andreasabel
Copy link
Contributor Author

So if this is an admissible generalization, ...

I ain't...

andreasabel added a commit to andreasabel/linear-base that referenced this issue Apr 12, 2022
Use case: stateful interpreter (`eval`) for C-like expressions `e`:
```haskell
let Ur value = HashMap.empty capacity (\ env -> move (evalState (eval e) env))
```
This pattern breaks the "jail" set by the type signature of
`HashMap`-allocation:
```haskell
empty :: Int -> (HashMap k v %1 -> Ur b) %1 -> Ur b
```
`HashMap` is not `Movable` but `Consumable`, so we can get rid of it before
`move`ing the result to `Ur`.
andreasabel added a commit to andreasabel/linear-base that referenced this issue Apr 12, 2022
Use case: stateful interpreter (`eval`) for C-like expressions `e`:
```haskell
let Ur value = HashMap.empty capacity (\ env -> move (evalState (eval e) env))
```
This pattern breaks the "jail" set by the type signature of
`HashMap`-allocation:
```haskell
empty :: Int -> (HashMap k v %1 -> Ur b) %1 -> Ur b
```
`HashMap` is not `Movable` but `Consumable`, so we can get rid of it before
`move`ing the result to `Ur`.
andreasabel added a commit to andreasabel/linear-base that referenced this issue Apr 12, 2022
Use case: stateful interpreter (`eval`) for C-like expressions `e`:
```haskell
let Ur value = HashMap.empty capacity (\ env -> move (evalState (eval e) env))
```
This pattern breaks the "jail" set by the type signature of
`HashMap`-allocation:
```haskell
empty :: Int -> (HashMap k v %1 -> Ur b) %1 -> Ur b
```
`HashMap` is not `Movable` but `Consumable`, so we can get rid of it before
`move`ing the result to `Ur`.
@andreasabel
Copy link
Contributor Author

@aspiwack : I am back to evalState, see

If you have other ideas how to write https://gist.github.com/andreasabel/f5c877491d32b653efba44cb283ba490#file-interpretermain-hs , please let me know.

andreasabel added a commit to andreasabel/linear-base that referenced this issue Apr 16, 2022
Use case: stateful interpreter (`eval`) for C-like expressions `e`:
```haskell
let Ur value = HashMap.empty capacity (\ env -> move (evalState (eval e) env))
```
This pattern breaks the "jail" set by the type signature of
`HashMap`-allocation:
```haskell
empty :: Int -> (HashMap k v %1 -> Ur b) %1 -> Ur b
```
`HashMap` is not `Movable` but `Consumable`, so we can get rid of it before
`move`ing the result to `Ur`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants