2

I am beginner to Haskell Im trying to make neuron to do that I need to generate random numbers for the weights of neurones but I'm stuck at function random it provokes an infinite loop I can't figure where the problem is, in addition when I ask in terminal when compiled take 3 random it always give me the same numbers I want it to take different random numbers each time

l = [1,0,1,1,0,0,1,0]

toDec :: [Int] -> Float
toDec []     = 0
toDec (x:xs) = fromIntegral  x+2*(toDec xs)

next :: [Int] -> [Int]
next xs = xs'
 where xs' = v:(init xs)
       v   = xor (last xs) (xs!!4)

random :: [Float]
random = ran l
       where ran l = ( (toDec l) /  255.0):(ran (next l))

-- simple neuron
data Neuron = Neuron [Float]
      deriving (Read,Show)

n = Neuron (take 3 random)
2
  • 5
    Haskell is a pure language. This means that a function's result depends only on its arguments and nothing else. If you want the numbers to be different every time, you need to give it some sort of seed as argument, and make it different every time. Commented Oct 11, 2020 at 2:21
  • Haskell is a pure language that happens to provide quite decent libraries for generating pseudo-random numbers. If statistical quality of the random numbers is of any concern, this is what you want to use, rather than reinventing the stuff. See at School of Haskell for example. Note: your question seems to come up periodically into SO in various forms, for example here. Commented Oct 11, 2020 at 8:27

1 Answer 1

2

You function works perfectly fine: it generates an infinite list of pseudorandom numbers.

(It's not a particularly good PRNG – for serious applications you should better use a library, random-fu is very extensive – but for educational purposes it's fine.)

But well, you need to be clear what this actually means. Because random is just a value of type [Float], it of course is always the same list. You can still use it for obtaining multiple different finite lists, by splitting up the single infinite one:

n₀, n₁, n₂ :: Neuron
(n₀:n₁:n₂:_) = Neuron <$> splits 3 random

-- | @splits n l@ gives a list of sublists of @l@, each of which has length @n@.
--   If the sublists are concatenated again, you get back @l@.
splits :: Int -> [a] -> [[a]]
splits nPerList l = case splitAt nPerList l of
   (h,[]) -> [h]
   (h,t) -> h : splits nPerList t

If you want something that behaves like the “random functions” in imperative languages, i.e. something that gives a different value each time it's called... well that's not a function then, because a function must for given input yield always the same result. However you can implement it as an action in a suitable monad. In an imperative language, there would be an implicit state of the PRNG. You can have that in Haskell too, except the state is explicit (which actually has a lot of advantages for reliability).

import Control.Monad.Trans.State

type RandSupply = State [Float]

oneRandom :: RandSupply Float
oneRandom = do
  ~(h:t) <- get   -- This is a bit of a hack†
  put t
  return h

randomNeuron :: Int -> RandSupply Neuron
randomNeuron nWeights = Neuron <$> replicateM nWeights oneRandom

Then you can write code like

import Control.Monad

     (`evalState`random) $ do
         ...
         n <- randomNeuron 3
         ...
         n₅ <- randomNeuron 5
         ...

and n and n₅ will have different weights, because the state of the supply-list has changed in between.


The irrefutable match ~(h:t) means that the action can fail badly if you try to use it with only a finite supply of random numbers. Again: the proper thing to do is to use a library for random numbers, rather than rolling your own.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you for your reply, yeah as you said, Because random is just a value of type [Float], it of course is always the same list, and to get more values I just have to type take 10 random for example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.