Sté*_*ent 2 arrays io monads haskell io-monad
我有一个这样的功能:
jac :: Int -> Int -> [Int] -> [Int] -> IOArray (Int,Int) Double -> IO Double
jac m k mu nu arr
| nu!!0 == 0 = return 1
| length nu > m && nu!!m > 0 = return 0
| m == 1 = return $ x!!0^(nu!!0) * theproduct (nu!!0)
| k == 0 && CONDITION = XXX
| otherwise = YYY
Run Code Online (Sandbox Code Playgroud)
在CONDITION必须检查该元素(1,1)的数组arr不同于0。但得到这个元素,一个必须做
element <- readArray arr (1,1)
Run Code Online (Sandbox Code Playgroud)
我不知道该怎么办。除外unsafePerformIO。在这里使用安全吗?我的意思是:
| k == 0 && unsafePerformIO (readArray arr (1,1)) /= 0 = XXX
Run Code Online (Sandbox Code Playgroud)
否则,我该怎么办?
让我们对您的问题进行简化。
假设我们要执行以下功能。它告诉我们两个Int值是否都等于0。问题是,它包含一个IO。您当前的方法是这样的:
-- THIS IS BAD CODE! This could easily cause unexpected behaviour.
areBothZero :: Int -> IO Int -> IO Bool
areBothZero a b
| a == 0 && unsafePerformIO b == 0 = return True
| otherwise = return False
Run Code Online (Sandbox Code Playgroud)
这表明对单子的误解。在Haskell中,unsafePerformIO通常不应使用一般规则,除非您想获得纯计算无法实现的某种效果。但是,使用monad操作是完全可以实现的,而monad操作则unsafePerformIO完全安全。
这就是我们实现这一目标的方式。首先,在以下内容之外编写逻辑IO:
areBothZeroLogic :: Int -> Int -> Bool
areBothZeroLogic a b
| a == 0 && b == 0 = True
| otherwise = False
Run Code Online (Sandbox Code Playgroud)
然后,将其传递到所需的IO逻辑:
areBothZeroIO :: Int -> IO Int -> IO Bool
areBothZeroIO a mb = do
b <- mb -- Use do-notation to work with the value 'inside' the IO:
return $ areBothZeroLogic a b
Run Code Online (Sandbox Code Playgroud)
立即,这将IO逻辑与纯逻辑分开。这是Haskell中的基本设计原则,您应该始终遵循。
现在,解决您的问题。
您的问题更加混乱,并且还有其他几个问题,这向我暗示您尚未考虑如何最好地将问题分解为较小的香料。但是,一个更好的解决方案可能看起来像这样,也许有更好的名字:
-- Look here! vvvvvv vvvvvv
jacPure :: Int -> Int -> [Int] -> [Int] -> Double -> Double
jacPure m k mu nu arrVal
| nu!!0 == 0 = 1
| length nu > m && nu!!m > 0 = 0
| m == 1 = x!!0^(nu!!0) * theproduct (nu!!0)
| k == 0 && arrVal /= 0 = XXX
| otherwise = YYY
jac :: Int -> Int -> [Int] -> [Int] -> IOArray (Int,Int) Double -> IO Double
jac m k mu nu arr = do
arrVal <- readArray arr (1,1) -- Use do-notation to work with the value 'inside' the IO:
return $ jacPure m k mu nu arrVal
Run Code Online (Sandbox Code Playgroud)
您应该立即看到为什么这会好得多。实施逻辑时,谁在乎领域中发生的事情IO?IO在纯逻辑中包含一个字眼,就像是告诉作者要打印的书的酸性程度,这与他们的工作无关。总是分开逻辑和IO!
当然,还有其他方式可以做到这一点,并且有些方法可能会比我建议的方法更好。但是,无法通过您提供的代码知道最佳路径。您应该致力于更多地了解monad,并更好地使用monad,以便您可以自己做出判断。
我怀疑这个问题是由于对摩纳德人和摩纳德行动缺乏了解造成的。如果您是初学者,建议阅读LYAH的相关章节,对初学者也有帮助。
| 归档时间: |
|
| 查看次数: |
157 次 |
| 最近记录: |