我有一个递归函数,它接收一个包含多个字段的数据对象,例如:
data MyState = {
first :: Int,
second :: String,
third :: Bool,
...
}
type Result = Int
Run Code Online (Sandbox Code Playgroud)
这个递归函数在执行期间改变它并将它传递给自己以备下次执行。它看起来如下:
-- This is a pseudocode, just to give an idea about the workflow.
process :: MyState -> Result
process st = go st
where go st | first == 1 = (go . changeFunc1) st
| first == 2 = (go . changeFunc2) st
| otherwise = generateResult st
changeFunc1 :: MyState -> MyState
changeFunc1 st | third st …Run Code Online (Sandbox Code Playgroud) 我是Haskell的新手,需要帮助。我试图建立必须以某种方式唯一的新数据类型,所以我决定使用UUID作为唯一标识符:
data MyType = MyType {
uuid :: UUID,
elements :: AnotherType
}
Run Code Online (Sandbox Code Playgroud)
这样,我可以执行以下操作:
instance Eq MyType where
x == y = uuid x == uuid y
x /= y = not (x == y)
Run Code Online (Sandbox Code Playgroud)
问题是,所有(对我而言)已知的UUID生成器都生成IO UUID,但是如上所述,我需要在纯代码中使用它。您能否建议是否有任何方法可以从IO UUID中提取UUID,或者是否有更好的方法可以在Haskell中完成我需要的工作?谢谢。
更新
感谢所有出色的建议和代码示例。从这里发布的内容可以说,您不能破坏参照透明性,但是有一些聪明的方法可以解决问题而又不破坏它,下面的答案中列出了可能是最佳的方法。
根据提供的有关State Monad的建议,我还可以使用一种替代方法进行自我探索:
type M = State StdGen
type AnotherType = String
data MyType = MyType {
uuid :: UUID,
elements :: AnotherType
} deriving (Show)
mytype :: AnotherType -> M MyType
mytype x = do
gen <- get …Run Code Online (Sandbox Code Playgroud) 我正在学习 Haskell 并尝试从书中构建一个示例。\n当我在 GHCI 中使用“:l BetterPredicate”命令加载代码时,出现以下错误:
\n\nPrelude> :l BetterPredicate\n[1 of 2] Compiling RecursiveContents ( RecursiveContents.hs, interpreted )\n\nRecursiveContents.hs:12:32: warning: [-Wtabs]\n Tab character found here.\n Please use spaces instead.\n[2 of 2] Compiling Main ( BetterPredicate.hs, interpreted )\n\nBetterPredicate.hs:3:1: error:\n Failed to load interface for \xe2\x80\x98System.Time\xe2\x80\x99\n Perhaps you meant\n System.CPUTime (from base-4.9.1.0)\n System.Cmd (from process-1.4.3.0)\n System.Mem (from base-4.9.1.0)\n Use -v to see a list of the files searched for.\nFailed, modules loaded: RecursiveContents.\nRun Code Online (Sandbox Code Playgroud)\n\n这是我试图编译的代码:
\n\nimport Control.Monad (filterM)\nimport System.Directory (Permissions (..), getModificationTime, getPermissions)\nimport …Run Code Online (Sandbox Code Playgroud)