Skip to main content
Add recursion tag, correct some quoting.
Source Link
rolfl
  • 98.2k
  • 17
  • 220
  • 419

I've been learning Haskell for a few weeks after coming from a C# background. I've written a function to return a number of unique Ints from a specified range:

module MrKWatkins.Random (
    uniqueRandomInts
) where

import System.Random
import qualified Data.IntSet as I

uniqueRandomInts :: RandomGen g => (Int, Int) -> Int -> g -> ([Int], g)
uniqueRandomInts range@(min, max) n rng
    | n < 0             = error "n must be positive"
    | n > max - min + 1 = error "n is too large for range"
    | otherwise         = recursion n I.empty ([], rng)
    where 
        recursion n used (xs, rng)
            | n == 0          = (xs, rng)
            | I.member x used = recursion n used (xs, rng')
            | otherwise       = recursion (n-1) (I.insert x used) (x:xs, rng')
            where 
                (x, rng') = randomR range rng

Then to produce 5 numbers in the (inclusive) range 1 -> 10 the call would be something like:

uniqueRandomInts (1, 10) 5 $ mkStdGen 42

Firstly I have a few specific questions:

  1. I've prefixed my module name with MrKWatkinsMrKWatkins to distinguish it as my module. (Muchmuch as I would with a namespace in C#). Is this common practice, or would I be better with a single word for the module name that is more descriptive?
  2. I've done some pre-condition checking on the parameters, throwing exceptions if they're not satisfied. Is this common practice in Haskell, and is this the best way to do it?
  3. I've used a nested function for the recursion. Would I be better off separating this out into a top level function that I don't export from the module?
  4. I've reused some variable names in the recursion function, hiding the ones from the parent scope. Should I use different names instead?

On top of those if there is any advice on style, better ways to implement the above or just general advice would be greatly appreciated.

I've been learning Haskell for a few weeks after coming from a C# background. I've written a function to return a number of unique Ints from a specified range:

module MrKWatkins.Random (
    uniqueRandomInts
) where

import System.Random
import qualified Data.IntSet as I

uniqueRandomInts :: RandomGen g => (Int, Int) -> Int -> g -> ([Int], g)
uniqueRandomInts range@(min, max) n rng
    | n < 0             = error "n must be positive"
    | n > max - min + 1 = error "n is too large for range"
    | otherwise         = recursion n I.empty ([], rng)
    where 
        recursion n used (xs, rng)
            | n == 0          = (xs, rng)
            | I.member x used = recursion n used (xs, rng')
            | otherwise       = recursion (n-1) (I.insert x used) (x:xs, rng')
            where 
                (x, rng') = randomR range rng

Then to produce 5 numbers in the (inclusive) range 1 -> 10 the call would be something like:

uniqueRandomInts (1, 10) 5 $ mkStdGen 42

Firstly I have a few specific questions:

  1. I've prefixed my module name with MrKWatkins to distinguish it as my module. (Much as I would with a namespace in C#) Is this common practice, or would I be better with a single word for the module name that is more descriptive?
  2. I've done some pre-condition checking on the parameters, throwing exceptions if they're not satisfied. Is this common practice in Haskell, and is this the best way to do it?
  3. I've used a nested function for the recursion. Would I be better off separating this out into a top level function that I don't export from the module?
  4. I've reused some variable names in the recursion function, hiding the ones from the parent scope. Should I use different names instead?

On top of those if there is any advice on style, better ways to implement the above or just general advice would be greatly appreciated.

I've been learning Haskell for a few weeks after coming from a C# background. I've written a function to return a number of unique Ints from a specified range:

module MrKWatkins.Random (
    uniqueRandomInts
) where

import System.Random
import qualified Data.IntSet as I

uniqueRandomInts :: RandomGen g => (Int, Int) -> Int -> g -> ([Int], g)
uniqueRandomInts range@(min, max) n rng
    | n < 0             = error "n must be positive"
    | n > max - min + 1 = error "n is too large for range"
    | otherwise         = recursion n I.empty ([], rng)
    where 
        recursion n used (xs, rng)
            | n == 0          = (xs, rng)
            | I.member x used = recursion n used (xs, rng')
            | otherwise       = recursion (n-1) (I.insert x used) (x:xs, rng')
            where 
                (x, rng') = randomR range rng

Then to produce 5 numbers in the (inclusive) range 1 -> 10 the call would be something like:

uniqueRandomInts (1, 10) 5 $ mkStdGen 42

Firstly I have a few specific questions:

  1. I've prefixed my module name with MrKWatkins to distinguish it as my module (much as I would with a namespace in C#). Is this common practice, or would I be better with a single word for the module name that is more descriptive?
  2. I've done some pre-condition checking on the parameters, throwing exceptions if they're not satisfied. Is this common practice in Haskell, and is this the best way to do it?
  3. I've used a nested function for the recursion. Would I be better off separating this out into a top level function that I don't export from the module?
  4. I've reused some variable names in the recursion function, hiding the ones from the parent scope. Should I use different names instead?

On top of those if there is any advice on style, better ways to implement the above or just general advice would be greatly appreciated.

Tweeted twitter.com/#!/StackCodeReview/status/408496553989795840
deleted 1 characters in body; edited tags; edited title
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

Function To Produce Unique Random Numbersto produce unique random numbers

I've been learning Haskell for a few weeks after coming from a C# background. I've written a function to return a number of unique IntsInts from a specified range:

module MrKWatkins.Random (
    uniqueRandomInts
) where

import System.Random
import qualified Data.IntSet as I

uniqueRandomInts :: RandomGen g => (Int, Int) -> Int -> g -> ([Int], g)
uniqueRandomInts range@(min, max) n rng
    | n < 0             = error "n must be positive"
    | n > max - min + 1 = error "n is too large for range"
    | otherwise         = recursion n I.empty ([], rng)
    where 
        recursion n used (xs, rng)
            | n == 0          = (xs, rng)
            | I.member x used = recursion n used (xs, rng')
            | otherwise       = recursion (n-1) (I.insert x used) (x:xs, rng')
            where 
                (x, rng') = randomR range rng

Then to produce 5 numbers in the (inclusive) range 1 -> 10 the call would be something like:

uniqueRandomInts (1, 10) 5 $ mkStdGen 42

Firstly I have a few specific questions:

  1. I've prefixed my module name with MrKWatkins to distinguish it as my module. (Much as I would with a namespace in C#) Is this common practice, or would I be better with a single word for the module name that is more descriptive?
  2. I've done some pre-condition checking on the parameters, throwing exceptions if they're not satisfied. Is this common practice in Haskell, and is this the best way to do it?
  3. I've used a nested function for the recursion. Would I be better off separating this out into a top level function that I don't export from the module?
  4. I've reused some variable names in the recursion function, hiding the ones from the parent scope. Should I use different names instead?

On top of those if there is any advice on style, better ways to implement the above or just general advice it would be greatly appreciated.

Function To Produce Unique Random Numbers

I've been learning Haskell for a few weeks after coming from a C# background. I've written a function to return a number of unique Ints from a specified range:

module MrKWatkins.Random (
    uniqueRandomInts
) where

import System.Random
import qualified Data.IntSet as I

uniqueRandomInts :: RandomGen g => (Int, Int) -> Int -> g -> ([Int], g)
uniqueRandomInts range@(min, max) n rng
    | n < 0             = error "n must be positive"
    | n > max - min + 1 = error "n is too large for range"
    | otherwise         = recursion n I.empty ([], rng)
    where 
        recursion n used (xs, rng)
            | n == 0          = (xs, rng)
            | I.member x used = recursion n used (xs, rng')
            | otherwise       = recursion (n-1) (I.insert x used) (x:xs, rng')
            where 
                (x, rng') = randomR range rng

Then to produce 5 numbers in the (inclusive) range 1 -> 10 the call would be something like:

uniqueRandomInts (1, 10) 5 $ mkStdGen 42

Firstly I have a few specific questions:

  1. I've prefixed my module name with MrKWatkins to distinguish it as my module. (Much as I would with a namespace in C#) Is this common practice, or would I be better with a single word for the module name that is more descriptive?
  2. I've done some pre-condition checking on the parameters, throwing exceptions if they're not satisfied. Is this common practice in Haskell, and is this the best way to do it?
  3. I've used a nested function for the recursion. Would I be better off separating this out into a top level function that I don't export from the module?
  4. I've reused some variable names in the recursion function, hiding the ones from the parent scope. Should I use different names instead?

On top of those if there is any advice on style, better ways to implement the above or just general advice it would be greatly appreciated.

Function to produce unique random numbers

I've been learning Haskell for a few weeks after coming from a C# background. I've written a function to return a number of unique Ints from a specified range:

module MrKWatkins.Random (
    uniqueRandomInts
) where

import System.Random
import qualified Data.IntSet as I

uniqueRandomInts :: RandomGen g => (Int, Int) -> Int -> g -> ([Int], g)
uniqueRandomInts range@(min, max) n rng
    | n < 0             = error "n must be positive"
    | n > max - min + 1 = error "n is too large for range"
    | otherwise         = recursion n I.empty ([], rng)
    where 
        recursion n used (xs, rng)
            | n == 0          = (xs, rng)
            | I.member x used = recursion n used (xs, rng')
            | otherwise       = recursion (n-1) (I.insert x used) (x:xs, rng')
            where 
                (x, rng') = randomR range rng

Then to produce 5 numbers in the (inclusive) range 1 -> 10 the call would be something like:

uniqueRandomInts (1, 10) 5 $ mkStdGen 42

Firstly I have a few specific questions:

  1. I've prefixed my module name with MrKWatkins to distinguish it as my module. (Much as I would with a namespace in C#) Is this common practice, or would I be better with a single word for the module name that is more descriptive?
  2. I've done some pre-condition checking on the parameters, throwing exceptions if they're not satisfied. Is this common practice in Haskell, and is this the best way to do it?
  3. I've used a nested function for the recursion. Would I be better off separating this out into a top level function that I don't export from the module?
  4. I've reused some variable names in the recursion function, hiding the ones from the parent scope. Should I use different names instead?

On top of those if there is any advice on style, better ways to implement the above or just general advice would be greatly appreciated.

Source Link
MrKWatkins
  • 161
  • 1
  • 10

Function To Produce Unique Random Numbers

I've been learning Haskell for a few weeks after coming from a C# background. I've written a function to return a number of unique Ints from a specified range:

module MrKWatkins.Random (
    uniqueRandomInts
) where

import System.Random
import qualified Data.IntSet as I

uniqueRandomInts :: RandomGen g => (Int, Int) -> Int -> g -> ([Int], g)
uniqueRandomInts range@(min, max) n rng
    | n < 0             = error "n must be positive"
    | n > max - min + 1 = error "n is too large for range"
    | otherwise         = recursion n I.empty ([], rng)
    where 
        recursion n used (xs, rng)
            | n == 0          = (xs, rng)
            | I.member x used = recursion n used (xs, rng')
            | otherwise       = recursion (n-1) (I.insert x used) (x:xs, rng')
            where 
                (x, rng') = randomR range rng

Then to produce 5 numbers in the (inclusive) range 1 -> 10 the call would be something like:

uniqueRandomInts (1, 10) 5 $ mkStdGen 42

Firstly I have a few specific questions:

  1. I've prefixed my module name with MrKWatkins to distinguish it as my module. (Much as I would with a namespace in C#) Is this common practice, or would I be better with a single word for the module name that is more descriptive?
  2. I've done some pre-condition checking on the parameters, throwing exceptions if they're not satisfied. Is this common practice in Haskell, and is this the best way to do it?
  3. I've used a nested function for the recursion. Would I be better off separating this out into a top level function that I don't export from the module?
  4. I've reused some variable names in the recursion function, hiding the ones from the parent scope. Should I use different names instead?

On top of those if there is any advice on style, better ways to implement the above or just general advice it would be greatly appreciated.