Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8021073
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T21:52:07+00:00 2026-06-04T21:52:07+00:00

I’m trying to write a little game in Haskell, and there’s a fair amount

  • 0

I’m trying to write a little game in Haskell, and there’s a fair amount of state necessary to pass around. I want to try hiding the state with the State monad

Now I’ve run into a problem: functions which take the state and an argument were easy to write to work in the state monad. But there are also functions that just take the state as argument (and return a modified state, or possibly something else).

In one part of my code, I have this line:

let player = getCurrentPlayer state

I would like it to not take state, and instead write

player <- getCurrentPlayerM

currently, its implementation looks like this

getCurrentPlayer gameState = 
  (players gameState) ! (on_turn gameState)

and it seemed simple enough to make it work in the State monad by writing it like this:

getCurrentPlayerM = do state <- get
                       return (players state ! on_turn state)

However, that provokes complaints from ghc! No instance for (MonadState GameState m0) arising from a use of `get’, it says. I had already rewritten a very similar function, except that wasn’t nullary in its State monad form, so on a hunch, I rewrote it like this:

getCurrentPlayerM _ = do state <- get
                         return (players state ! on_turn state)

And sure enough, it works! But of course I have to call it as getCurrentPlayerM (), and I feel a little silly doing that. Passing in an argument was what I wanted to avoid in the first place!

An additional surprise: looking at its type in ghci I get

getCurrentPlayerM :: MonadState GameState m => t -> m P.Player

but if I try to set that explicitly in my code, I get another error: “Non type-variable argument in the constraint MonadState GameState m” and an offer of a language extension to permit it. I suppose it’s because my GameState is a type and not a typeclass, but why it’s accepted in practice but not when I try to be explicit about it I’m more confused about.

So to sum up:

  1. Why can’t I write nullary functions in the State monad?
  2. Why can’t I declare the type my workaround function actually has?
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T21:52:09+00:00Added an answer on June 4, 2026 at 9:52 pm

    The problem is that you don’t write type signatures for your functions, and the monomorphism restriction applies.

    When you write:

    getCurrentPlayerM = ...
    

    you are writing a top-level unary constrained value definition without a type declaration, so the Haskell compiler will try to infer a type for the definition. However, the monomorphism restriction (Literally: single-shape restriction) states that all top-level definitions with inferred type constraints have to resolve to concrete types, i.e. they mustn’t be polymorphic.


    To explain what I mean, take this simpler example:

    pi = 3.14
    

    Here, we define pi without a type, so GHC infers the type Fractional a => a, i.e. “any type a, as long as it can be treated like a fraction.” However, this type is problematic, because it means that pi is not a constant, even though it looks like it is. Why? Because the value of pi will be re-computed depending on what type we want it to be.

    If we have (2::Double) + pi, pi will be a Double. If we have (3::Float) + pi, pi will be a Float. Each time pi is used, it therefore has to be re-computed (because we can’t store alternative versions of pi for all possible fractional types, can we?). This is fine for the simple literal 3.14, but what if we wanted more decimals of pi and used a fancy algorithm that calculated it? We wouldn’t want it to be recomputed every time pi is used then, would we?

    This is why the Haskell Report states that top-level unary type-constrained definitions must have a single type (monomorphic), to avoid this problem. In this case, pi would get the default type of Double. You can change the default numeric types if you want, using the default keyword:

    default (Int, Float)
    
    pi = 3.14 -- pi will now be Float
    

    In your case, however, you are getting the inferred signature:

    getCurrentPlayerM :: MonadState GameState m => m P.Player
    

    It means: “For any state monad that stores GameStates, retrieve a player.” However, because the monomorphism restriction applies, Haskell is forced to try to make this type non-polymorphic, by choosing a concrete type for m. However, it can’t find one, because there is no type defaulting for state monads like there is for numbers, so it gives up.

    You either want to give your function an explicit type signature:

    getCurrentPlayerM :: MonadState GameState m => m P.Player
    

    … but you will have to add the FlexibleContexts Haskell language extension for it to work, by adding this at the top of your file:

    {-# LANGUAGE FlexibleContexts #-}
    

    Or, you can specify explicitly which state monad you want:

    getCurrentPlayerM :: State GameState P.Player
    

    You can also disable the monomorphism restriction, by adding the extension for that; it is much better to add type signatures, however.

    {-# LANGUAGE NoMonomorphismRestriction #-}
    

    PS. If you have a function that takes your state as a parameter, you can use:

    value <- gets getCurrentPlayer
    

    You should also look into using Lenses with State monads, which lets you write very clean code for implicit state passing.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I want to count how many characters a certain string has in PHP, but
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I am trying to render a haml file in a javascript response like so:
I have a French site that I want to parse, but am running into
I want use html5's new tag to play a wav file (currently only supported
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
i want to parse a xhtml file and display in UITableView. what is the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.