在Haskell中提升State monad的值 [英] Lifting a value in the State monad in Haskell

查看:137
本文介绍了在Haskell中提升State monad的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我的解决函数需要花费一个数独生成器/求解器在Haskell中进行学习。在 UArray 中,但返回一个 State Int(UArray ...),这样它也可以返回最大难度级别它是在解决问题时找到的。



这是我迄今为止的功能(仍处于非常实验性的早期阶段):

  import Control.Monad.State(State,put)
import Control.Monad.Trans.Class(lift)
import Data.Array.MArray(thaw)
导入Data.Array.ST(runSTUArray)
导入Data.Array.Unboxed(UArray)

- ...

类型单元格= Word16

解决:: UArray(Int,Int)单元格 - > State Int(UArray(Int,Int)Cell)
solve grid = do
return $ runSTUArray $ do
arr< - 解冻网格
lift $ put 42
return arr

它对可变数组没有任何作用。我试图用放入42 来检查它,但目前出现以下错误:

 •无法将种类'*'与'*  - > *'
当匹配'ST'类型时
•在'do'块的句柄中:lift $ put 42
在'($)'的第二个参数中,也就是
'do arr < - 解冻网格
提升$ put 42
返回arr'
在'($)'的第二个参数中,即
'runSTUArray
$ do arr< - 解冻网格
lift $ put 42
return arr'
|
128 |提升$ put 42
| ^^^^^^^^^^^^^


解决方案

在将 State monad更改为一个元组(Int,Grid)
$ $ p $ import Control.Monad.ST(ST,runST)
import Data.Array.MArray冻结,解冻,writeArray)
导入Data.Array.ST(STUArray)
导入Data.Array.Unboxed(UArray)
导入Data.Word(Word16)

类型Cell = Word16
类型Grid = UArray(Int,Int)单元格

solve :: Grid - > (Int,Grid)
解析grid =
runST $ do
mut < - thaw grid :: ST s(STUArray s(Int,Int)Cell)
writeArray mut 0,0)0 - 测试我实际上可以写
frozen< - 冻结mut
return(42,冻结)

这适用于我的应用程序。


I am writing a Sudoku generator/solver in Haskell as a learning exercise.

My solve function takes in a UArray but returns a State Int (UArray ...) so that it can also return the maximum difficulty level that it found while solving.

This is my function so far (still in the very experimental early stage):

import Control.Monad.State       (State, put)
import Control.Monad.Trans.Class (lift)
import Data.Array.MArray         (thaw)
import Data.Array.ST             (runSTUArray)
import Data.Array.Unboxed        (UArray)

-- ...

type Cell = Word16

solve :: UArray (Int, Int) Cell -> State Int (UArray (Int, Int) Cell)
solve grid = do
  return $ runSTUArray $ do
    arr <- thaw grid
    lift $ put 42
    return arr

It does not really do anything with the mutable array yet. I am simply trying to get it to type check with the put 42, but currently get the following error:

  • Couldn't match kind ‘*’ with ‘* -> *’
    When matching the kind of ‘ST’
  • In a stmt of a 'do' block: lift $ put 42
    In the second argument of ‘($)’, namely
      ‘do arr <- thaw grid
          lift $ put 42
          return arr’
    In the second argument of ‘($)’, namely
      ‘runSTUArray
         $ do arr <- thaw grid
              lift $ put 42
              return arr’
     |
 128 |     lift $ put 42
     |     ^^^^^^^^^^^^^

解决方案

I was able to get a slight variation to compile and run after changing the State monad to a tuple (Int, Grid):

import Control.Monad.ST    (ST, runST)
import Data.Array.MArray   (freeze, thaw, writeArray)
import Data.Array.ST       (STUArray)
import Data.Array.Unboxed  (UArray)
import Data.Word (Word16)

type Cell = Word16
type Grid = UArray (Int, Int) Cell

solve :: Grid -> (Int, Grid)
solve grid =
  runST $ do
    mut <- thaw grid :: ST s (STUArray s (Int, Int) Cell)
    writeArray mut (0, 0) 0 -- test that I can actually write
    frozen <- freeze mut
    return (42, frozen)

This works fine for my application.

这篇关于在Haskell中提升State monad的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆