2017-08-01 75 views
0

我有一個函數鏈接狀態單子

step :: Int -> State Int Int 
step n = get >>= \x -> put (x `div` n) >> return (x `mod` n) 

λ> runState (step 25) 41 
(16,1) 

如何運行的step個序列,與n不同的值,並使用來自最後一步的狀態下每一步?

所以示例中的步驟將是如下

一步一個產生(16,1)然後我想用作輸入我與n = 10下一步應該產生(6, 2)。第一步添加1,第一步添加16,新建n。

n = 25 gives (16,1) then 
n = 10 gives (6,2) then 
n = 5 gives (1,3) then 
n = 1 gives (0,4) 

我知道在這裏使用State可能不正確;但我試圖用它來學習。

可能的目標是與狀態monad一起實現此功能。

greedy :: Double -> Int 
greedy owed = snd $ foldl go (pennies,0) [25, 10, 5, 1] 
    where 
    pennies      = floor . (*100) $ owed 
    go (remaining,counter) coin = (remaining',counter') 
     where 
     remaining' = remaining `mod` coin 
     counter' = counter + remaining `div` coin 
+0

你說的是不是'一步其他任何1 >>第2步>>第3步? – Cubic

+0

@Cubic,我修改了我的問題。 – matthias

回答

3

功能,

mapM step [25,10,5,1] 

或在每個[25,10,5,1]列表的更一般的

traverse step [25,10,5,1] 

運行step。調用

runState (mapM step [25,10,5,1]) 41 

運行初始狀態設置爲41的函數,返回步驟輸出列表和最終狀態。

([16,1,0,0],0) 

如果您想要列出狀態和輸出,只需修改step以包含它們。

步驟N = GET >> = \ X - >把(X div N)>>返回((X mod N),(X div N))

,或者換一種說法

step n = do 
    x <- get 
    let (r,x') = (x `mod` n,x `div` n) 
    put x' 
    return (r,x') 

結果是,([(16,1),(1,0),(0,0),(0,0)],0),仍然不是你要找的,但更接近。恐怕我不明白你的方程的詳細程度,不足以得到你正在尋找的東西,但這應該有助於理清州的一部分,讓你專注於數學。

作出上述go功能:

go n = do 
    (r,c) <- get 
    let (r',c') = (r `mod` n, c + (r `div` n)) 
    put (r',c') 
    return (r',c') 

runState (mapM go [25,10,5,1]) (41,0) 

產量,

([(16,1),(6,2),(1,3),(0,4)],(0,4)) 

希望幫助

+0

我似乎無法得到它的工作.. :( – matthias

+0

'runState(mapM步驟[25,10,5,1])41 ==>([16,1,0,0],0)'this是我得到的... – matthias

+0

我的錯誤,沒有測試就回答,對不起,它只返回輸出,會後修復 –