Reputation: 63
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)
Upvotes: 2
Views: 481
Reputation: 120711
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.
Upvotes: 2