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 8691163
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T00:04:07+00:00 2026-06-13T00:04:07+00:00

Possible Duplicate: Creating unique labels in Haskell I’ve got a datatype Person and some

  • 0

Possible Duplicate:
Creating unique labels in Haskell

I’ve got a datatype Person and some input data from which I will create the Persons.

I’d like to have each Person have its own ID (let’s say integers [0..]). I could do this with recursion, but since I’m doing this in Haskell, I’d like to understand the monads. The State Monad is probably the best for this job, I suppose?

The thing is, I don’t really understand lots of things: when am I inside the monad (what functions can use the inside), how do I plumb them together, how do I make the ‘tick’ function advance, etc…

So I’m currently stuck with this: the tick function probably works, but I’m not sure how to use it; and how to successively get its value for the construction of Persons.

import Control.Monad.State

data Person = Person {
  id   :: Int,
  name :: String
} deriving Show

type MyState = Int
startState = 0

tick :: State MyState Int
tick = do
  n <- get
  put (n+1)
  return n

names = ["Adam","Barney","Charlie"]

-- ??? -> persons = [Person 0 "Adam", Person 1 "Barney", Person 2 "Charlie"]

main = do
  print $ evalState tick startState
  -- ???

EDIT: would this be somehow easier with Data.Unique or Data.Unique.Id? How would it be used in my situation?

  • 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-13T00:04:08+00:00Added an answer on June 13, 2026 at 12:04 am

    Well, I think the best way to explain is to just write some code.

    First of all, you would want too hide the inner workings of the monad in which you currently work. We’ll do this with a type alias, but there are more powerful ways, see this chapter from Real World Haskell.

    type PersonManagement = State Int
    

    The reason for this is in case you’ll add more things to PersonManagement later and its good practice to use the black box abstraction.

    Together with the definition of PersonManagement, you should expose the primitive operations that define this monad. In your case, we have only the tick function for now which looks almost the same, but with a clearer signature and a more suggestive name.

    generatePersonId :: PersonManagement Int
    generatePersonId = do
        n <- get
        put (n+1)
        return n
    

    Now, all of the above should reside in a separate module. On top of this we can define more complex operations, like the creation of a new Person:

    createPerson :: String -> PersonManagement Person
    createPerson name = do
        id <- generatePersonId
        return $ Person id name
    

    By now you probably realized that PersonManagement is a type of computation, or a process which encapsulates logic for dealing with Persons and PersonManagement Person is a computation from which we obtain a person object. That’s very nice, but how do we actually get the persons we just created and do something with them, like printing their data at the console. Well, we need a “run” method, which runs our process and gives us the result.

    runPersonManagement :: PersonManagement a -> a
    runPersonManagement m = evalState m startState
    

    The runPersonManagement runs the monad and gets the final result while performing all the side effects in the background (in your case, ticking the Int state). This uses the evalState from the state monad, and it should also reside in the module described above since it knows about the inner workings of the monad. I assumed, that you always want to start the person id from a fixed value, identified by startState.

    So for example if we wanted to create two persons and print them to the console, the program would be something like:

    work :: PersonManagement (Person, Person)
    work = do
        john <- createPerson "John"
        steve <- createPerson "Steve"
        return (john, steve)
    
    main = do
        let (john, steve) = runPersonManagement work
        putStrLn $ show john
        putStrLn $ show steve
    

    Output:

    Person {id = 0, name = "John"}
    Person {id = 1, name = "Steve"}
    

    Since PersonManagement is a full fledged monad you can also use generic functions from Control.Monad for example. Let’s say you want to create a list of persons from a list of names. Well, that’s just the map function lifted in the domain of monads – it’s called mapM.

    createFromNames :: [String] -> PersonManagement [Person]
    createFromNames names = mapM createPerson names
    

    Usage:

    runPersonManagement $ createFromNames ["Alice", "Bob", "Mike"] =>
        [
            Person {id = 0, name = "Alice"},
            Person {id = 1, name = "Bob"},
            Person {id = 2, name = "Mike"}
        ]
    

    And examples could go on.

    To answer one of your questions – you work in the PersonManagement monad only when you need the services provided by that monad – in this case, the generatePersonId function or you need functions which in turn require the monad’s primitives like work which needs the createPerson function which in turn needs to run inside the PersonManagement monad because it needs the self-incrementing counter. If you have, for example, a function that checks whether two persons have the same data, you wouldn’t need to work inside the PersonManagement monad and it should be a normal, pure function of type Person -> Person -> Bool.

    To really understand how to work with monads you’ll just have to go through a lot of examples. Real World Haskell is a great start and so is Learn you a Haskell.

    You should also look into some libraries which use monads to see how they are made and how people use them. One great example are parsers, and parsec is a great place to start.

    Also, this paper by P. Wadler provides some very nice examples and of course, there are many more resources that are ready to be discovered.

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

Sidebar

Related Questions

Possible Duplicate: Firefox session cookies I'm creating a website in which users are allowed
Possible Duplicate: What is the 'new' keyword in JavaScript? creating objects from JS closure:
Possible Duplicate: Instance as a static class property I got a problem about creating
Possible Duplicate: Rails: select unique values from a column Lets say I have 5000
Possible Duplicate: Creating and managing a Facebook app from a Business Account I know
Possible Duplicate: Generate unique random numbers in Java I am creating a lottery app
Possible Duplicate: How to execute sql statements from a C program? I'm creating a
Possible Duplicate: Creating or assigning variables from a dictionary in Python Hello we have
Possible Duplicate: Change language programatically in Android I am creating Application which is a
Possible Duplicate: Creating, opening and printing a word file from C++ Hi, I need

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.