Home > other >  How do I make random choice from two options in haskell properly?
How do I make random choice from two options in haskell properly?

Time:09-22

I want to write a function that would take a String and a Char and randomly either prepend or append the Char to the String.

I am wrote this, but it doesn't work because of some the type signature is the last line:

join :: RandomGen g => [Char] -> Char -> g -> ([Char], g)
join letters letter g = if inverse
                        then (letter:letters, newG)
                        else (letters    [letter], newG)
                        where (inverse, newG) = random g :: (Bool, RandomGen)

error i get:

Expecting one more argument to ‘RandomGenExpected a type, but ‘RandomGen’ has kind ‘* -> ConstraintIn an expression type signature: (Bool, RandomGen)
  In the expression: random g :: (Bool, RandomGen)
  In a pattern binding:
    (inverse, newG) = random g :: (Bool, RandomGen)

So how do I properly generate a boolean value and return the new generator from the function?

CodePudding user response:

The type of random g is not (Bool, RandomGen) since RandomGen is a typeclass , not a type.

We can specify the type of inverse through a type application and thus implement this as:

{-# LANGUAGE TypeApplication #-}

join :: RandomGen g => [Char] -> Char -> g -> ([Char], g)
join letters letter g
  | inverse = (letter:letters, newG)
  | otherwise = (letters    [letter], newG)
  where (inverse, newG) = random @Bool g

That being said, since inverse is used by a guard (or if … then … else …) the compiler knows that inverse is a Bool, and thus it can work out the types for inverse and newG. It is thus sufficient to define join as:

join :: RandomGen g => [Char] -> Char -> g -> ([Char], g)
join letters letter g
  | inverse = (letter:letters, newG)
  | otherwise = (letters    [letter], newG)
  where (inverse, newG) = random g

It might also be better to use another name than join, since join :: Monad m => m (m a) -> m a is a function often used when working with monads.

  • Related