- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我正在尝试做一些新颖的事情(我认为),但我不是
对 Haskell 类型级编程有足够的经验,可以自己解决。
我有一个免费的 monad 描述了一些要执行的效果(一个 AST,如果那是
你滚动的方式),我想根据一些描述来解释它
预期的效果。
到目前为止,这是我的代码::
{-# LANGUAGE DeriveFunctor, FlexibleInstances, GADTs, FlexibleContexts #-}
import Control.Monad.Free -- from package 'free'
data DSL next
= Prompt String (String -> next)
| Display String next
deriving (Show, Functor)
prompt p = liftF (Prompt p id)
display o = liftF (Display o ())
-- |Just to make sure my stuff works interactively
runIO :: (Free DSL a) -> IO a
runIO (Free (Prompt p cont)) = do
putStr p
line <- getLine
runIO (cont line)
runIO (Free (Display o cont)) = do putStrLn o; runIO cont
runIO (Pure x) = return x
greet :: (Free DSL ())
greet = do
name <- prompt "Enter your name: "
let greeting = "Why hello there, " ++ name ++ "."
display greeting
friendName <- prompt "And what is your friend's name? "
display ("It's good to meet you too, " ++ friendName ++ ".")
runTest :: Free DSL a -> _ -> Maybe a
,它应该像这样模糊地采用一个程序和一些“预期效果”的规范:
expect = (
(Prompt' "Enter your name:", "radix"),
(Display' "Why hello there, radix.", ()),
(Prompt' "And what is your friend's name?", "Bob"),
(Display' "It's good to meet you too, Bob.", ()))
expect
中的下一项相匹配来解释程序列表。然后关联的值(每对中的第二项)应作为该效果的结果返回给程序。如果所有效果都匹配,则程序的最终结果应返回为
Just
.如果有什么不匹配,
Nothing
应该返回(稍后我将扩展它,以便它返回一条信息性错误消息)。
expect
tuple 没用,因为它的类型是一个巨大的东西,我不能写一个通用的
runTest
功能结束。我遇到的主要问题是我应该如何表示这个预期的意图序列,以便我可以编写一个可以针对任何程序使用任何序列的函数
Free DSL a
.
expected
使用 HList 还是什么?序列? 最佳答案
程序测试Free f a
只是程序的解释器Free f a -> r
产生一些结果r
您正在寻找的是一种为程序构建解释器的简单方法,该解释器断言程序的结果是您所期望的。解释器的每一步都将解开 Free f
来自程序的指令或描述一些错误。他们会有那种类型
Free DSL a -> Either String (Free DSL a)
| | ^ the remaining program after this step
| ^ a descriptive error
^ the remaining program before this step
DSL
中的每个构造函数进行测试。 .
prompt'
预计
Prompt
具有特定值并向函数提供响应值以查找下一步。
prompt' :: String -> String -> Free DSL a -> Either String (Free DSL a)
prompt' expected response f =
case f of
Free (Prompt p cont) | p == expected -> return (cont response)
otherwise -> Left $ "Expected (Prompt " ++ show expected ++ " ...) but got " ++ abbreviate f
abbreviate :: Free DSL a -> String
abbreviate (Free (Prompt p _)) = "(Free (Prompt " ++ show p ++ " ...))"
abbreviate (Free (Display p _)) = "(Free (Display " ++ show p ++ " ...))"
abbreviate (Pure _) = "(Pure ...)"
display'
预计
Display
具有特定值。
display' :: String -> Free DSL a -> Either String (Free DSL a)
display' expected f =
case f of
Free (Display p next) | p == expected -> return next
otherwise -> Left $ "Expected (Display " ++ show expected ++ " ...) but got " ++ abbreviate f
pure'
预计
Pure
具有特定值
pure' :: (Eq a, Show a) => a -> Free DSL a -> Either String ()
pure' expected f =
case f of
Pure a | a == expected -> return ()
otherwise -> Left $ "Expected " ++ abbreviate' (Pure expected) ++ " but got " ++ abbreviate' f
abbreviate' :: Show a => Free DSL a -> String
abbreviate' (Pure a) = "(Pure " ++ showsPrec 10 a ")"
abbreviate' f = abbreviate f
prompt'
和
display'
我们可以轻松构建
expect
风格的解释器.
expect :: Free DSL a -> Either String (Free DSL a)
expect f = return f >>=
prompt' "Enter your name:" "radix" >>=
display' "Why hello there, radix." >>=
prompt' "And what is your friend's name?" "Bob" >>=
display' "It's good to meet you too, Bob."
main = either putStrLn (putStrLn . const "Passed") $ expect greet
Expected (Prompt "Enter your name:" ...) but got (Free (Prompt "Enter your name: " ...))
expect :: Free DSL a -> Either String (Free DSL a)
expect f = return f >>=
prompt' "Enter your name: " "radix" >>=
display' "Why hello there, radix." >>=
prompt' "And what is your friend's name? " "Bob" >>=
display' "It's good to meet you too, Bob."
Passed
关于haskell - 如何将指定为自由单子(monad)的程序与预期指令的描述进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32673144/
这是我正在调试的函数: boolean adin_memory(char* buffer, int size_chunck, int end_flag){ global_buffer = my
我正在尝试为具有自由 float 底座的机器人计算末端执行器空间速度雅可比行列式。由于自由 float 基数,雅可比应该包含一个基数组件和一个操纵器注释(参见 https://spart.readth
procedure FreeListObjects( l : TStrings); var i : integer; BEGIN FOR i := 0 TO l.Count -1 DO BEG
我正在探索 Haskell 中的选项,这些选项可以让我将业务逻辑与底层系统的技术实现分开。例如,在 Web 服务器的上下文中,将 Web 服务器处理其接收的信息的方式与其读取和写入数据库的方式分开。要
我的目标是使用来自 ActiveMQ 的 WebSphere Liberty Appserver(完整的 Java EE 标准)使用消息。不幸的是,我不知道如何配置 WebSphere Liberty
我以这种方式分配了一个非方阵,但我不确定我是否正确使用了释放 float **matrix_alloc(int m /* rows */, int n /* columns */) { int
我在阅读 refuting the notion 之后的第 13.5 节内置运算符不参与重载决议,并注意到没有关于 operator->* 的部分。它只是一个通用的二元运算符。 它的兄弟operato
我正在尝试使用 Libelf 库来获取有关某些 elf 文件的一些信息。但我不断收到这些“对 [...] 的 undefined reference ”。我从 synaptic 安装了 libelf(
我有创建动态结构数组的波纹管代码。 #include #include #include typedef struct { int flag; char* ip; } ip_mo
我是 StackOverflow 的新人。我现在正在学习C指针。 这是我的代码: #include #include int alloc(int* p){ p = (int*) mallo
我是 StackOverflow 的新人。我现在正在学习C指针。 这是我的代码: #include #include int alloc(int* p){ p = (int*) mallo
我正在用 C 编写一个程序,我需要读入一个文件并打印出每个至少 4 个字符长的字符串。我在分配要使用的内存时遇到问题。字符串可以任意长。我试图将缓冲区分配给文件的大小,然后在最后释放它,但我显然错过了
我尝试用 C 语言编写 ls 命令,但 -R 选项有问题。 输出: /Applications/Atom.app/Contents/Resources/app/apm/node_modules/es5
我正在编写一个 shell,但在执行内存检查时遇到问题,因为 valgrind 无法正常运行。 我遇到了这样的错误(我自己杀死了它): ==19703== Memcheck, a memory err
我有这样一段代码: void *write_parallel(void *num_for_chunk) { struct rusage *sum = (struct rusage*) mall
当使用包含 200-300 个整数(以空格分隔)的输入 .txt 文件运行此代码时,我在使用 fprintf 语句的 for 循环之前收到错误。 我不确定 qsort 是否导致了此错误或为什么会发生此
我试图告诉 Websphere Liberty 我的 log4j2.xml 文件在哪里,但它不起作用。 在我的文件 jvm.options 中,我配置: -Dlog4j.configurationFi
从 websphere liberty 16 迁移到 19.0.0.1 我遇到以下异常:运行存储过程后关闭连接,出现以下异常: EJB threw an unexpected (non-declare
当对大小为 210*8 的种子数据集运行此代码时,我在预测函数中的 qsort() 行之后收到错误。它不在 qsort() 之后执行。 我不确定 qsort 是否导致了此错误或为什么会发生此错误,但如
这个问题已经有答案了: Facing an error "*** glibc detected *** free(): invalid next size (fast)" (2 个回答) 已关闭 9
我是一名优秀的程序员,十分优秀!