Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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 新范围在';do';符号_Haskell_Monads - Fatal编程技术网

Haskell 新范围在';do';符号

Haskell 新范围在';do';符号,haskell,monads,Haskell,Monads,我正在尝试编写一个递归函数,它可以对Data.Vector.unbox.Mutable“Vector”进行变异,尽管我认为这个问题适用于任何一元代码 作为一个人为的例子: import Data.Vector.Unboxed as U import Data.Vector.Unboxed.Mutable as M import Control.Monad import Control.Monad.ST import Control.Monad.Primitive f :: U.Vector I

我正在尝试编写一个递归函数,它可以对Data.Vector.unbox.Mutable“Vector”进行变异,尽管我认为这个问题适用于任何一元代码

作为一个人为的例子:

import Data.Vector.Unboxed as U
import Data.Vector.Unboxed.Mutable as M
import Control.Monad
import Control.Monad.ST
import Control.Monad.Primitive

f :: U.Vector Int -> U.Vector Int
f x = runST $ do
        y <- U.thaw x
        add1 y 0
        U.freeze y

add1 :: (PrimMonad m) => MVector (PrimState m) Int -> Int -> m()
add1 v i | i == M.length v = return ()
add1 v i = do
     c <- M.unsafeRead v i
     M.unsafeWrite v i (c + 1)
     add1 v (i+1)
撇开错误不谈,这还不是最理想的:我不想这样做(y'这个怎么样

f :: U.Vector Int -> U.Vector Int
f x = runST $ do
    y <- U.thaw x
    let add1 i | i == length x = return ()
               | otherwise     = do
            c <- M.unsafeRead y i
            M.unsafeWrite y i (c+1)
            add1 (i+1)
    add1 0
    U.freeze y
f::U.Vector Int->U.Vector Int
f x=runST$do

很酷,我不知道你可以在do语句中使用let-in-line!非常感谢!你应该把对
length
的调用从循环中提出来。@augustss Yep,我觉得在引入新的语法形式时,最好只给出最简单(而不是最有效)的例子。这是一个有意识的教学选择。
f x = let len = U.length x
          y = U.thaw x
          add1 i | i == len = return ()
          add1 i = do
             y' <- y
             c <- M.unsafeRead y' i
             M.unsafeWrite y' i (c+1)
             add1 (i+1)
      in runST $ do
            add1 0
            y' <- y
            U.freeze y'
couldn't match type 'm0' with 'ST s'
couldn't match type 's' with 'PrimState m0'
f :: U.Vector Int -> U.Vector Int
f x = runST $ do
    y <- U.thaw x
    let add1 i | i == length x = return ()
               | otherwise     = do
            c <- M.unsafeRead y i
            M.unsafeWrite y i (c+1)
            add1 (i+1)
    add1 0
    U.freeze y