我正在尝试使用StateT [Int] IO Int
编写一个函数,只是为了了解更多信息。
在f :: StateT [Int] IO Int
f = state $ \xs -> update (error "I want a") xs
update :: Int -> [Int] -> (Int, [Int])
update x [] = (x, [])
update x (y:ys) = (x+y, ys)
中,我想访问let x = return 55 :: StateT [Int] IO Int
的最后一个类型参数中的runStateT
:
*Main> :t runStateT
runStateT :: StateT s m a -> s -> m (a, s)
以下是我想称之为:
runStateT (f x) [1,2,3]
引用IO (Int, [Int])
:
(56, [2,3])
我希望能够运行它:
a
从GHCI获得以下内容,即55
被打印:
+ 1
由于内部[1,2,3]
,即(56, [2,3])
,a
,即来自$price = array($pricer['incvat']);
,会返回$price[] = $pricer['incvat'];
。
如何编写上述功能,访问button_style = ttk.Style()
button_style.configure("button_style.TButton", relief=tk.RAISED,
width = 20, padding=6, font=('Helvetica', 12) )
self.button = ttk.Button (self.myContainer1, text="Browse", style='button_style.TButton',
command = self.browse_file)
self.button.grid(row = 0,column = 3,padx=5, pady=10, ipadx=5, ipady=5)
?
答案 0 :(得分:5)
好的,这就是你想要的:
>>> let x = return 55 :: StateT [Int] IO Int
>>> runStateT (f x) [1,2,3]
(56, [2,3])
所以让我们从那里开始工作。
使用f
,我们可以推断出它的类型 -
f :: StateT [Int] IO Int -> StateT [Int] IO Int
请注意问题中f
的给定类型与[{1}}的差异 - 即f
是StateT [Int] IO Int
类型值之间的函数,而不是该类型的值。
要定义f
,我们需要(>>=) :: Monad m => m a -> (a -> m b) -> m b
。这将允许我们输入类型为StateT [Int] IO Int
的输入,并在Int
输入计算上运行一些计算。
f x = x >>= \i -> state (splitAt 1) >>= \[j] -> return (i + j)
或者,使用do-notation:
f x = do
i <- x
[j] <- state (splitAt 1)
return (i + j)
这给了我们我们想要的结果。
虽然这有效,但它非常非惯用。不是将monadic值作为输入传递给函数并将它们绑定到函数内部,而是定义使用常规值并返回monadic值的函数,使用bind运算符(>>=
)在
因此定义
更为正常shiftAdd :: Int -> StateT [Int] IO Int
shiftAdd i = do
[j] <- state (splitAt 1)
return (i + j)
所以现在我们不仅可以运行
>>> runStateT (shiftAdd 55) [1,2,3]
(56,[2,3])
但也
>>> runStateT (shiftAdd 55 >>= shiftAdd >>= shiftAdd)
(61,[])
它仍然不像以下那样惯用:
splitAt
使它变得不必要(如果状态列表为空则会抛出异常)解决这个问题让我们:
shiftAdd' :: (Monad m, Num a) => a -> StateT [a] m a
shiftAdd' i = state $ \js -> case js of
[] -> (i, [])
j : js -> (i + j, js)
哪种方法很好:
>>> runStateT (return 55 >>= shiftAdd') [1,2,3]
(56,[2,3])
>>> runStateT (return 55 >>= shiftAdd' >>= shiftAdd' >>= shiftAdd') [1,2,3]
(61,[])
>>> runStateT (return 55 >>= shiftAdd' >>= shiftAdd' >>= shiftAdd') []
(55,[])