Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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
Haskell 哈斯克尔:循环?_Haskell - Fatal编程技术网

Haskell 哈斯克尔:循环?

Haskell 哈斯克尔:循环?,haskell,Haskell,我是Haskell的新手,希望在Haskell中复制以下内容。接近环路的最佳方式是什么 kCenterX = kCols / 2; kCenterY = kRows / 2; for(i=0; i < rows; ++i) // rows { for(j=0; j < cols; ++j) // columns { for(m=0; m < kRows; ++m) // kernel rows

我是Haskell的新手,希望在Haskell中复制以下内容。接近环路的最佳方式是什么

    kCenterX = kCols / 2;
    kCenterY = kRows / 2;

for(i=0; i < rows; ++i)              // rows
{
for(j=0; j < cols; ++j)          // columns
{
    for(m=0; m < kRows; ++m)     // kernel rows
    {
        mm = kRows - 1 - m;      // row index of flipped kernel

        for(n=0; n < kCols; ++n) // kernel columns
        {
            nn = kCols - 1 - n;  // column index of flipped kernel

            // index of input signal, used for checking boundary
            ii = i + (m - kCenterY);
            jj = j + (n - kCenterX);

            // ignore input samples which are out of bound
            if( ii >= 0 && ii < rows && jj >= 0 && jj < cols )
                out[i][j] += in[ii][jj] * kernel[mm][nn];
        }
    }
}
}
kCenterX=kCols/2;
kcentry=kRows/2;
对于(i=0;i=0&&ii=0&&jj
因为(乍一看)您正在做一些相当棘手的索引工作,所以您可以使用命令式风格来移植它。否则,您将不得不深入研究该算法的原因,并以不同的方式表达它

这里有一个例子可以帮助你。下面的C代码(我之所以选择它,是因为它在赋值的左侧有索引数学)

void示例(常量int*输入、int大小、int*输出){
//假设输出初始化为零
对于(int i=0;i
可以从字面上翻译为Haskell,如下所示:

import Control.Monad (forM_)
import Data.Array.ST
import Data.Array

example :: Array Int Int -> Array Int Int
example input = runSTArray $ do
    output <- newArray (bounds input) 0
    forM_ (indices input) $ \i -> do
        let newi = i `div` 2
        writeArray output newi (input ! i)
    return output
import-Control.Monad(表单)
导入Data.Array.ST
导入数据。数组
示例::Array Int->Array Int
示例输入=runSTArray$do
输出do
设newi=i`div`2
writeArray输出newi(输入!i)
返回输出
(尽管这与我们在惯用的Haskell中表达该函数的方式相去甚远。)

如果你对这个符号有什么特别的问题,如何扩展到多维数组,一旦你得到了纯
数组,如何使用它,或者其他什么,我建议你作为一个单独的问题来问


我还要说,这项任务使用了一些更复杂的Haskell概念(主要是因为我们必须使用一些技巧来用函数式语言说祈使句),如果您是Haskell的新手,那么这可能不是最好的起点。祝你好运

在查看代码一段时间后,它似乎是一个应用具有0边界(截断访问)的卷积内核的代码。所以我的第一步是。实际上,我会选择一个使用合适数据类型的,比如版本。在这种情况下,我将把你的函数写成:

outarray = runIdentity $ convolveOutP (outAs 0) kernel inarray
其中
runIdentity
来自Data.Functor.Identity,用于打开monad
convolveOutP
返回其中的数据

但实现功能,而不是找到它,完全是另一项任务。我将从一个合适的数据类型开始,例如from(Repa也使用它)。它们没有2D索引,但我们可以使用。或者已经有人帮我们做了,让我们从这个开始

首先,我们的数组索引现在不需要从零开始。所以我们可以定义一个中心为零的内核:

import Data.Array.Unboxed

kernelShape = ((-1,-1), (1,1))
-- Simple blurring kernel function for example
weight (x,y) = 2**(-2-fromIntegral (abs x)-fromIntegral (abs y))
kernel :: UArray (Int,Int) Float
kernel = listArray kernelShape [weight (x,y) | (x,y) <- range kernelShape]
-- We can check the weights add up:
one = sum $ elems kernel
import Data.Array.unbox
核形状=(-1,-1,(1,1))
--以简单模糊核函数为例
重量(x,y)=2**(-2-从积分(abs x)-从积分(abs y))
内核::UArray(Int,Int)浮点

kernel=listary kernelShape[weight(x,y)|(x,y)惯用的Haskell会以一种非常不同的方式来实现这一点。我认为你应该在Haskell中学习函数式编程的一些基本概念。如果你不习惯它,一开始会很奇怪,但在我看来,一旦你进入它,它会很有趣。通过以一种更好的方式为FP重新构造问题,事实上,它可能会变得非常简单。首先,你可能认为您必须递归地编写函数,并且您必须学会这样做,但如果问题合适,可能会有更高阶的函数使问题变得几乎微不足道。FP不是命令式概念的新语法。一般来说,您不需要在Haskell中重写代码。您只需从描述开始在Haskell中编写代码说明输入和输出是什么以及它们是如何关联的,而不是从描述你将如何用另一种语言做某事开始。因为(一目了然)你正在做一些相当棘手的索引工作,你可以使用命令式风格来移植它。否则你必须深入研究算法的原因,并用不同的方式表达它。“请为我翻译这段代码”是学习新习语的糟糕方法。我建议你尝试学习Haskell,在遇到困难时急切地问问题。像这里所做的那样,不带方向地问一个广泛的问题并不是学习这门语言的有效方法。像
linear
这样的库可能会有所帮助。
import Data.Array.Unboxed

kernelShape = ((-1,-1), (1,1))
-- Simple blurring kernel function for example
weight (x,y) = 2**(-2-fromIntegral (abs x)-fromIntegral (abs y))
kernel :: UArray (Int,Int) Float
kernel = listArray kernelShape [weight (x,y) | (x,y) <- range kernelShape]
-- We can check the weights add up:
one = sum $ elems kernel
convolve kernel inA = accumArray (+) 0 (bounds inA) placedterms
  where placedterms = [((x,y), (kernel!(lx,ly)) * (inA!(x+lx,y+ly))) |
                       (x,y) <- indices inA, 
                       (lx,ly) <- indices kernel, 
                       inRange (bounds inA) ((x+lx),(y+ly))]

convolvedkernel = convolve kernel kernel :: UArray (Int,Int) Float