zipWith Haskell

时间:2012-12-04 22:40:23

标签: haskell

我创建了这种数据类型和功能:

type Bit = Int

randomFloatList :: Int -> [Float]
randomFloatList seed = randoms (mkStdGen seed)

我想创建一个使用zipWith的函数。该函数有seed作为参数用于randomFloatList,如果随机元素介于0和噪声之间,则该位被更改。我试图这样做,但我遇到了zipWith

的困难

感谢。

2 个答案:

答案 0 :(得分:4)

我相信您想要获取Bit的列表并使用随机列表来决定是否更改原始列表。 (如果没有,请澄清。)

channel :: Int -> Float -> [Bit] -> [Bit]
channel seed noise xs = zipWith (alterBit noise) (randomFloatList seed) xs

请注意,您不需要一些括号 - 您不需要用于功能应用的括号,仅用于分组。

alterBit :: Float -> Float -> Bit -> Bit
alterBit noise random bit | random <= noise = alter bit
                          | otherwise = bit

同样,我删除了对我正在使用的列表的任何引用 - zipWith将向此函数发送它需要的单个元素浮点列表和位。

我冒昧地定义了

data Bit = O | I deriving Show

并且只能想到一个改变功能:

alter :: Bit -> Bit
alter O = I
alter I = O

让我们测试一下:

> take 6 $ randomFloatList 3
[0.10321328,0.98988104,0.46191382,0.8553592,0.7980472,0.35561606]

> map (<= 0.5) $ take 6 $ randomFloatList 3
[True,False,True,False,False,True]

> channel 3 0.5 [O,O,O,O,O,O]
[I,O,I,O,O,I]
是的,这改变了它应该的那些。

答案 1 :(得分:0)

zipWith的签名是(a -> b -> c) -> [a] -> [b] -> [c]。这意味着它可以映射一个在两个列表中包含两个参数的函数。

我认为,在你的情况下,你只想在一个列表上映射一个函数(因为你的函数alterBit只接受一个参数),所以你必须使用map,而不是{ {1}}。

另请注意zipWithseed将无法在noise中显示,除非您在模块中将其定义为常量或将其明确传递给alterBit