鉴于变换器:: T2 of T1 of M0
的嵌套,我如何利用:: T2 of M0
,:: M2
?
这是一个例子:我正在编写一些需要读取,记录和状态的函数。定义:
gameRoutine :: WriterT [String] (ReaderT Env (State Viable)) NUM
如果我想打个电话
stateFunction :: State Viable NUM
甚至是stateWithReaderFunction :: ReaderT Env (State Viable) NUM
,
我可以使用lift
:
gameRoutine = do
x <- lift . lift $ stateFunction
y <- lift $ stateWithReaderFunction
但我如何致电writerFunction :: Writer [String] a
?
如何致电writerStateFunction :: WriterT [String] (State Viable) NUM
(gameRoutine
定义之间的差异为ReaderT
图层缺失?)
显然,我不想将其定义提升为gameRoutine
之一。
答案 0 :(得分:5)
嗯,基本上mtl
的想法是你不需要这样做。您可以使用通用签名
writerStateFunction
,而不是使用该特定签名定义writerStateFunction' :: (MonadWriter [String] m, MonadState Viable m)
=> m NUM
Reader
然后,尝试使用此环境的环境有一个额外的MonadWriter
图层并不重要:这不会阻止monad同时拥有MonadState
和<html>
<head>
<title>Example</title>
</head>
<script src='https://www.google.com/recaptcha/api.js'></script>
<script>
//This is our DOM on JQUERY or JAVASCRIPT named as main.js
$(function() {
//First we have to listen on a event click (button) and extract the values of the inputs
$('body').on('click','.myButtonClass', function() {
$email = $('#emailID').val();
$password = $('#passwordID').val();
$recaptcha = $('textarea').val();
//We save in a object our values
$x = {
action:'validate',
email:$email,
password:$password
captcha:$recaptcha
};
//We execute ajax calling a php file for POST method
$.post('file.php',$x,function(callback) {
$('.answer').html(callback);
});
});
});
/*END OF DOM AND MAIN.JS*/
</script>
<body>
<form>
<input type="email" id="emailID" placeholder="Write here your email">
<input type="password" id="passwordID" placeholder="Write here your password">
<input type="button" class="myButtonClass">
</form>
<!--Your div recaptcha. This give you the page recaptcha google when you are into your configuration Change the XXXX for your SITE KEY numbers and letters -->
<div class="g-recaptcha" data-sitekey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"></div>
<!--This will be where we display the answer with ajax, in the element who have the class answer-->
<div class="answer"></div>
</body>
</html>
<?php
//this is your file.php
require_once 'recaptchalib.php';
//BEGIN OUR PHP FILE WHERE WE'LL RECIEVE ALL THE DATA FROM THE AJAX FILE
//we save the action sended trough ajax
$action = $_POST['action'];
if ( $action == 'validate' ) :
//WE SAVE A EMAIL
$email = addslashes($_POST['email']);
//WE SAVE THE PASSWORD FOR THIS EXAMPLE
$password = addslashes($_POST['password']);
//We paste here one more time our secret key
$secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$response = null;
$reCaptcha = new ReCaptcha($secret);
$captcha = $_POST["captcha"];
//WE VALIDATE IF THE INPUTS ARE CORRECTLY INPUT
$input = strlen($email)*strlen($password);
if ( $_POST["captcha"] ) :
$response = $reCaptcha->verifyResponse(
$_SERVER["REMOTE_ADDR"],
$captcha
);
endif;
//We validate if exists a response success from google recaptcha and if is it, we continue
if ( $response != null && $response->success ) :
//if the inputs were in
if ( $input > 0 ) :
echo 'OWW YEAH, YOU VALIDATE CORRECTLY GOOGLE RECAPTCHA AND YOUR EMAIL IS '.$email.' AND YOUR PASSWORD IS: '.$password;
else :
echo 'Sorry but you are not fill all the inputs. All are required, please refresh the page and try it again';
endif;
else :
echo 'Hey, man! Chillout, first validate the google recpatcha and fill the inputs and click the button for continue. Thanks';
endif;
endif;
/*END OF PHP FILE*/
//BEGIN OUR FORM IN HTML
?>
功能
答案 1 :(得分:3)
你可以将Writer w a
提升到MonadWriter
个实例,例如:
import Control.Monad.Writer (MonadWriter, Writer, runWriter, tell)
lift' :: MonadWriter w m => Writer w a -> m a
lift' wr = do
let (a, w) = runWriter wr
tell w -- manually re-log the log msg
return a -- wrap value into new context
然后,你可以写一下:
gameRoutine :: WriterT [String] (ReaderT Env (State Viable)) NUM
gameRoutine = do
a <- lift' writerFunction
只要writerFunction :: Writer [String] a
可以专门用a ~ NUM
。