question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Generic monad functions with SeqT

See original GitHub issue

Repro

let test_b : SeqT<ReaderT<Input, State<MenuState, seq<MenuMessage>>>> =
    monad.plus' {
        let! read_fail_a = ask
        let! state_fail_a = get
        
        let! read_fail_b = lift ask
        let! state_fail_b = lift get
        
        let! read_success_c = SeqT.lift ask
        let! state_success_c = SeqT.lift get
        
        return Exit
    }

Actual behavior

c works as expected, but a and b result in the following compilation error:

Type constraint mismatch when applying the default type 'obj' for a type inference variable.
No overloads match for method 'op_GreaterGreaterEquals'. 
Known return type: ReaderT<Input,State<MenuState,seq<MenuMessage>>>
Known type parameters: < obj , (seq<seq<MenuMessage>> -> ReaderT<Input,State<MenuState,seq<MenuMessage>>>) >

Expected behavior

I expected to be able to use generic functions like ask and get with SeqT without lifting, but maybe I’m misunderstanding how deep my nested monads are or I’ve set the wrong type parameters or something like that? Maybe I can’t mix side effects and monad.plus?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
gustycommented, Nov 19, 2021

That’s fine. One more detail: I see you’re using a strict monad.plus, by writing monad.plus', but not sure if you read this section of the docs.

There it states:

For layered monads (monad transformers) the general rule is: the monad is strict unless at least one of its constituent types is lazy, in that case the whole monad becomes lazy.

Following. there is a small snippet that helps you when in doubt whether the monad is strict or not.

In your sample, both ReaderT and State are lazy, so even if this version of SeqT is strict (unlike the ideal implementation I mentioned in my previous comment), the whole combination should be a lazy one.

0reactions
harrissecommented, Nov 18, 2021

Thanks, I am mainly looking for the syntactic sugar to return multiple elements (or ()) which SeqT seems to provide well enough. I was able to solve my problem with SeqT.lift ask and State.get |> ReaderT.lift |> SeqT.lift for ask and get respectively.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is this a generic transformer for any monad?
m x -> IO x) -> IO a is a monad transformer for IO applied to an arbitrary foreign monad m . It...
Read more >
Is a a MONAD in Haskell just the functional equivalent of a ...
In oop speak, monad is just an interface. Something is a monad if it is generic (i.e. can contain a type (i.e. the...
Read more >
Using Monads in C++ to Solve Constraints: 1. The List Monad
We'll call this function for_each , and we'll make it as generic as possible. ... The monad is actually defined by two functions....
Read more >
Scala Monads 101
* Monads have laws and there are 3 laws: Left identity, Right identity and Associativity. * This trait just descrive a generic monad...
Read more >
Combining free monads in F# - ploeh blog
... generic FreeT type, which enables you to stack monads. In F# ... In order to extract the contained monad, you can use...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found