我目前正在学习免费的monad,我正在尝试使用其中最简单,最常见的示例– Teletype
:
{-# LANGUAGE DeriveFunctor #-}
import Control.Monad.Free
data TeletypeF a = Put String a
| Get (String -> a)
deriving Functor
type Teletype = Free TeletypeF
许多教程解释了Teletype
单子程序中的IO
程序。例如:
-- Utilities
get = liftF $ Get id
put s = liftF $ Put s ()
-- Sample programs
echo :: Teletype ()
echo = do word <- get
if word == "\04" -- Ctrl-D
then return ()
else put word >> echo
hello :: Teletype ()
hello = do put "What is your name?"
name <- get
put "What is your age?"
age <- get
put ("Hello, " ++ name ++ "!")
put ("You are " ++ age ++ " years old!")
-- Interpret to IO
interpIO :: Teletype a -> IO a
interpIO = foldFree lift
where
lift (Put s a) = putStrLn s >> return a
lift (Get f) = getLine >>= return . f
我试图用另一种monad来解释它,即RWS monad。
这个想法是受this assignment上一次练习的启发。
我正在使用RWS
数据类型从Reader
部分获取输入,并在State
部分中累积输出。
但是,不幸的是,我无法使其正常运行。到目前为止,这是我的尝试:
import Control.Monad.Trans.RWS.Lazy hiding (get, put)
type TeletypeRWS = RWS [String] () [String]
-- Interpret to TeletypeRWS
interpRWS :: Teletype a -> TeletypeRWS a
interpRWS = foldFree lift
where
lift (Put s a) = state (\t -> ((), t ++ [s])) >> return a
lift (Get f) = reader head >>= local tail . return . f -- This is wrong
mockConsole :: Teletype a -> [String] -> (a, [String])
mockConsole p inp = (a, s)
where
(a, s, _) = runRWS (interpRWS p) inp []
运行TeletypeRWS
“程序”时,不会删除环境中的第一个值:
*Main> mockConsole hello ["john", "18"]
((),["What is your name?","What is your age?","Hello, john!","You are john years old!"])
我对更新Reader
有点不安,但是我不知道如何才能访问列表中的下一个值。 TeletypeRWS
的类型是根据上述练习选择的,因此我认为应该可以实现interpRWS
。
答案 0 :(得分:2)
我们不能使用 'use strict';
describe('Test Controller', function () {
var _myModalCtrl, _title, _scope;
var _modalInstance;
beforeEach(function () {
module('myApp');
inject(function ($controller, $rootScope) {
_scope = $rootScope.$new();
_modalInstance = {close: function () {
}};
_title = {
};
_myModalCtrl = $controller('myModalCtrl',
{
$scope: _scope,
$uibModalInstance: _modalInstance,
title: _title,
});
});
});
describe('Functions', function() {
it('Submit', function () {
_scope.updateFiles(); --> ** This is failing **
});
it('Cancel', function () {
_scope.cancel();
});
});
:在延续中它必须是参数化的,因此我们不能在此处应用foldFree
。相比之下,local
显式地为我们提供了实际的延续而无需泛化,因此可以使用。
iterM