递归函数中的Haskell无限循环

递归函数中的Haskell无限循环,haskell,deep-learning,Haskell,Deep Learning,我是Haskell的初学者,我想让neuron这样做,我需要为神经元的权重生成随机数,但我被困在函数随机中,它会引发无限循环 我想不出问题出在哪里,另外,当我在终端中询问编译时,取3个随机数,它总是给我相同的数字,我希望它每次取不同的随机数 l = [1,0,1,1,0,0,1,0] toDec :: [Int] -> Float toDec [] = 0 toDec (x:xs) = fromIntegral x+2*(toDec xs) next :: [Int] -&g

我是Haskell的初学者,我想让neuron这样做,我需要为神经元的权重生成随机数,但我被困在函数随机中,它会引发无限循环 我想不出问题出在哪里,另外,当我在终端中询问编译时,取3个随机数,它总是给我相同的数字,我希望它每次取不同的随机数

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)
您的函数工作得非常好:它生成无限多个伪随机数

(这不是一个特别好的PRNG——对于严肃的应用程序,您最好使用一个库,它非常广泛——但出于教育目的,它也可以。)

但你需要弄清楚这到底意味着什么。因为
random
只是
[Float]
类型的值,所以它当然总是相同的列表。通过拆分单个无限列表,您仍然可以使用它获取多个不同的有限列表:

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
n₀, N₁, N₂ :: 神经元
(n)₀:N₁:N₂:_) = 神经元随机分裂3次
--|@splits n l@给出了@l@的子列表,每个子列表都有长度@n@.
--如果再次连接子列表,则返回@l@.
拆分::Int->[a]->[[a]]
拆分nPerList l=在nPerList l处拆分的案例
(h,[])->[h]
(h,t)->h:splits nPerList t
如果你想要一个类似“随机函数”的东西在命令式语言中,即每次调用时给出不同值的东西…那么这不是一个函数,因为对于给定的输入,函数必须始终产生相同的结果。但是,您可以在适当的单子中将其实现为一个动作。在命令式语言中,PRNG会有一个隐式状态。您可以使用在Haskell中也是如此,除了状态是显式的(这实际上在可靠性方面有很多优势)

import Control.Monad.Trans.State
类型RandSupply=状态[浮动]
oneRandom::随机供应浮动
oneRandom=do
~(h:t)供体神经元
randomNeuron nWeights=神经元复制nWeights oneRandom
然后您可以编写如下代码

import Control.Monad

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

n Haskell是一种纯语言。这意味着函数的结果只取决于它的参数,而不取决于其他任何东西。如果你想让数字每次都不同,你需要给它一些种子作为参数,并使它每次都不同。Haskell是一种纯语言,恰好为生成伪随机数提供了相当不错的库dom数字。如果随机数字的统计质量值得关注,这是您想要使用的,而不是重新发明的东西。例如,请参阅。注意:您的问题似乎以各种形式定期出现。谢谢您的回答,是的,正如您所说,因为随机只是[Float]类型的值,它当然总是相同的列表,为了得到更多的值,我只需要输入10个随机值
import Control.Monad

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