Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell列表理解0和1_List_Haskell - Fatal编程技术网

List Haskell列表理解0和1

List Haskell列表理解0和1,list,haskell,List,Haskell,我正在尝试写一个函数 row :: Int -> Int -> [Int] row n v 它返回一个包含n个整数的列表,所有整数都是0,但vth元素除外,该元素必须是1 比如说, row 0 0 = [] row 5 1 = [1,0,0,0,0] row 5 3 = [0,0,1,0,0] 我是哈斯克尔的新手,在这方面有很多困难。特别是我不知道如何让它重复0。我理解从[1..n]构建列表的概念,但我只得到[1,2,3,4,5] 在此方面的任何帮助都将不胜感激。谢谢。包含两个临

我正在尝试写一个函数

row :: Int -> Int -> [Int]
row n v
它返回一个包含n个整数的列表,所有整数都是0,但vth元素除外,该元素必须是1

比如说,

row 0 0 = []
row 5 1 = [1,0,0,0,0]
row 5 3 = [0,0,1,0,0]
我是哈斯克尔的新手,在这方面有很多困难。特别是我不知道如何让它重复0。我理解从[1..n]构建列表的概念,但我只得到[1,2,3,4,5]


在此方面的任何帮助都将不胜感激。谢谢。

包含两个临时变量c和lst的简单递归循环。c代表计数,lst代表我们必须返回的列表

row :: Int -> Int -> [ Int ]
row 0 0 = []
row n v = rowHelp n v 1 [] where
    rowHelp n v c lst
            | c > n = lst
            | v == c = rowHelp n v ( c + 1 ) ( lst ++ [ 1 ] )
            | otherwise = rowHelp n v ( c + 1 ) ( lst ++ [ 0 ] )
~
~

haskell的有趣之处在于,它让您能够以表达算法的方式编写程序。因此,请尝试:

row n v = [if (x `mod` v==0) then 1 else 0  | x <- [1..n] ]
HTH Chris

试试:

let row n v = map (\x -> if x == v then 1 else 0) [1..n]

还有另一个解决方案,递归地建立列表:

row :: Int -> Int -> [Int]
row 0 _ = []
row n 1 = 1 : (row (n-1) 0)
row n m = 0 : (row (n-1) (m-1))
还有一个更可读的,其中取零:

row :: Int -> Int -> [Int]
row 0 _ = []
row n m = take (m - 1) zeros ++ [1] ++ take (n - m) zeros
    where zeros = (iterate id 0)

有一份全面的清单:

 row n v = [if x == v then 1 else 0 | x <- [1..n]]

我想根据Chris的解决方案演示一种自上而下的方法:

row n v = result           
    where
        result = take n numbers        -- our result will have a length of n
        numbers = map trans [1,2,..]   -- and is some transformation of
                                       -- the list of natural numbers
        trans e
           | e `mod` v == 0  = 1       -- let every v-th element be 1
           | otherwise       = 0       -- 0 otherwise
row n v = [(v-1, 0), (1, 1), (n-v, 0)] >>= (uncurry replicate)

这种风格强调函数式编程的思想,即写下某个特定值(如nv行)应该是什么,而不是试图写下函数的功能。让人想起一个关于鲜为人知的pragraming语言Sartre的著名笑话,我们可以说,在纯函数式编程中,函数什么都不做,它们就是这样

这里有一个单体解决方案:

row n v = result           
    where
        result = take n numbers        -- our result will have a length of n
        numbers = map trans [1,2,..]   -- and is some transformation of
                                       -- the list of natural numbers
        trans e
           | e `mod` v == 0  = 1       -- let every v-th element be 1
           | otherwise       = 0       -- 0 otherwise
row n v = [(v-1, 0), (1, 1), (n-v, 0)] >>= (uncurry replicate)
replicate函数将给定值重复多次,例如,replicate v-1 0给出了v-1 0的列表。uncurry用于修改复制,以便接受一个元组而不是两个单参数。有趣的操作符>>=是单子的心脏;对于列表,它与带有翻转参数的concatMap相同。

这也应该适用:

row n v = replicate (v-1)­ 0 ++ [1] ++ repl­icate (n-v)­ 0

最短的方法是fromEnum。这可能是最好的解决方案,因为它非常容易推广。可能是最聪明的解决方案,但也不一定是最容易阅读的解决方案。我刚开始使用类似Ankur的解决方案,但复制的重复让我感到不安。此解决方案为第0行提供[1],其中应计算为[].甚至更短:row n v=map from enum.==v[1..n]@Landei:shorter,但有点混淆了意思。嗨,沙布。如果您觉得您的问题已得到回答,请选择其中一个答案作为接受答案。这样,其他人就可以快速找到解决您问题的解决方案,而无需查看所有答案。你可以通过点击问题左边的复选标记来选择答案。创建一个无限列表,从开头开始对我来说似乎有点程序化。你写了两条语句,它们都做了一些事情,计算无限列表,然后取开头。这根本不是我写的事情应该是怎样的,而是如何去做,这就是你所说的不应该做的。map trans[1..n]似乎很容易阅读,不是吗?很抱歉,你不喜欢它,我没有说它是最有效或最短的源代码方式。似乎mod部分是你的发明,我没有看到问题中的任何一个。至少你的第二个例子是错误的。