gpt4 book ai didi

Haskell Monad 状态示例

转载 作者:行者123 更新时间:2023-12-02 10:40:56 29 4
gpt4 key购买 nike

我正在尝试 Haskell 的 Control.Monad.State通过尝试迭代字符串或整数的列表,对它们进行计数,并将字符串条目替换为整数 0 。我已经成功完成了计数部分,但未能创建替换列表。这是我的代码正确打印 [3,6]到屏幕上。我怎样才能让它创建所需的列表 [6,0,3,8,0,2,9,1,0]

module Main( main ) where

import Control.Monad.State

l = [
Right 6,
Left "AAA",
Right 3,
Right 8,
Left "CCC",
Right 2,
Right 9,
Right 1,
Left "D"]

scanList :: [ Either String Int ] -> State (Int,Int) [ Int ]
scanList [ ] = do
(ns,ni) <- get
return (ns:[ni])
scanList (x:xs) = do
(ns,ni) <- get
case x of
Left _ -> put (ns+1,ni)
Right _ -> put (ns,ni+1)
case x of
Left _ -> scanList xs -- [0] ++ scanList xs not working ...
Right i -> scanList xs -- [i] ++ scanList xs not working ...

startState = (0,0)

main = do
print $ evalState (scanList l) startState

最佳答案

[0] ++ scanList xs不起作用,因为 scanList xs不是列表,而是 State (Int,Int) [Int] 。要解决这个问题,您需要使用 fmap/<$> .

您还需要更改基本情况,以免状态值成为返回值。

scanList :: [Either String Int] -> State (Int, Int) [Int]
scanList [] = return []
scanList (x:xs) = do
(ns,ni) <- get
case x of
Left _ -> put (ns+1, ni)
Right _ -> put (ns, ni+1)
case x of
Left _ -> (0 :) <$> scanList xs
Right i -> (i :) <$> scanList xs

但是,为了进一步简化代码,最好使用 mapM/traversestate删除大部分递归样板和 get/put语法。

scanList :: [Either String Int] -> State (Int, Int) [Int]
scanList = mapM $ \x -> state $ \(ns, ni) -> case x of
Left _ -> (0, (ns+1, ni))
Right i -> (i, (ns, ni+1))

关于Haskell Monad 状态示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54603200/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com