我正在测试一个名为extractions的函数,它可以在任何列表上运行.
extractions :: [a] -> [(a,[a])]
extractions [] = []
extractions l = extract l []
where extract [] _ = []
extract (x:xs) prev = (x, prev++xs) : extract xs (x : prev)
Run Code Online (Sandbox Code Playgroud)
我想测试它,例如,用
import Test.QuickCheck.Batch
prop_len l = length l == length (extractions l)
main = runTests "extractions" defOpt [run prop_len]
Run Code Online (Sandbox Code Playgroud)
但这不会编译; 我必须为run或提供一个类型prop_len,因为QuickCheck无法生成[a],它必须生成具体的东西.所以我选择了Int:
main = runTests "extractions" defOpt [r prop_len]
where r = run :: ([Int] -> Bool) -> TestOptions …Run Code Online (Sandbox Code Playgroud) 我正在阅读一个使用以下示例的教程(我将稍微概括一下):
f :: Foo -> (Int, Foo)
...
fList :: Foo -> [Int]
fList foo = x : fList bar
where
(x, bar) = f foo
Run Code Online (Sandbox Code Playgroud)
我的问题在于,似乎你可以参考,x并且bar,通过名称,在获得它们的元组之外.如果我的猜测是正确的,这似乎就像在其他语言中解构参数列表一样.(换句话说,我没有做以下:)
fList foo = (fst tuple) : fList (snd tuple)
where
tuple = f foo
Run Code Online (Sandbox Code Playgroud)
我对这种行为是对的吗?在我读过的教程/书籍中,我从未见过它.有人能指出我有关这个问题的更多信息吗?
编辑:任何事情(列表,数组等)都可以以类似的方式进行解构,或者你只能用元组做到这一点吗?
我试图扩展一个递归下降的解析器来处理新的运算符,并使它们正确关联.最初只有四个运算符(+ - /*),它们都具有相同的优先级.我正在看的函数是parseExpRec函数:
parseExpRec :: Exp -> [Token] -> (Exp, [Token])
parseExpRec e [] = (e, [])
parseExpRec e1 (op : ts) =
let (e2, ts') = parsePrimExp ts in
case op of
T_Power -> parseExpRec (BinOpApp Power e1 e2) ts'
T_Plus -> parseExpRec (BinOpApp Plus e1 e2) ts'
T_Minus -> parseExpRec (BinOpApp Minus e1 e2) ts'
T_Times -> parseExpRec (BinOpApp Times e1 e2) ts'
T_Divide -> parseExpRec (BinOpApp Divide e1 e2) ts'
T_GreaterThan -> parseExpRec (BinOpApp GreaterThan e1 e2) …Run Code Online (Sandbox Code Playgroud) 我正在尝试在Haskell中创建一个Tree类型.我已经使用这个简单的数据构造函数来存储一个树,其中每个节点可以是空的,是包含整数的叶子,或者是包含一个整数的节点,该整数具有到另外两个叶子/节点的分支.这是我得到的:
module Tree ( Tree(Empty, Leaf, Node) ) where
data Tree = Empty
| Leaf Int
| Node Tree Int Tree
deriving(Eq, Ord, Show, Read)
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我需要使树类型多态.我试过用'a'代替'Int',但它似乎不起作用.是否有另一个系统使这些类型多态?
我正在编写一个小型命令式语言的编译器.目标语言是Java字节码,编译器在Haskell中实现.
我已经写了一个语言的前端 - 即我有一个词法分析器,解析器和类型检查器.我无法弄清楚如何进行代码生成.
我保留了一个表示局部变量堆栈的数据结构.我可以使用局部变量的名称查询此结构并获取其在堆栈中的位置.当我遍历语法树时传递这个数据结构,并在我进入和退出新范围时弹出和推送变量.
我弄清楚的是如何发出字节码.在终端发出字符串并将它们连接在更高的级别似乎是一个糟糕的解决方案,无论是清晰度还是性能方面.
tl; dr如何在使用语法树时发出字节码?
我需要能够编写一个函数来显示字符串中重复的单词并按顺序返回字符串列表并忽略非字母
例如,在拥抱提示
repetitions :: String -> [String]
repetitions > "My bag is is action packed packed."
output> ["is","packed"]
repetitions > "My name name name is Sean ."
output> ["name","name"]
repetitions > "Ade is into into technical drawing drawing ."
output> ["into","drawing"]
Run Code Online (Sandbox Code Playgroud) 基本上我需要做的是编写一个函数,它接受一个类型列表[(String, String)]并打印出内容,这样逐行输出如下所示:
FirstString : SecondString
FirstString : SecondString
Run Code Online (Sandbox Code Playgroud)
..etc,列表中的每个项目.我有以下代码,它打印出来,但由于某种原因,它打印出一行包含[(),()]在最后.
display :: Table -> IO ()
display zs = do {
xs <- sequence [putStrLn ( a ++ " = " ++ b) | (a, b) <- zs];
print xs
}
Run Code Online (Sandbox Code Playgroud)
有什么我做错了吗?
基本上我正在修改解析器以处理其他运算符.在我的更改之前,解析器的一部分看起来像这样:
parseExpRec e1 (op : ts) =
let (e2, ts') = parsePrimExp ts in
case op of
T_Plus -> parseExpRec (BinOpApp Plus e1 e2) ts'
T_Minus -> parseExpRec (BinOpApp Minus e1 e2) ts'
T_Times -> parseExpRec (BinOpApp Times e1 e2) ts'
T_Divide -> parseExpRec (BinOpApp Divide e1 e2) ts'
_ -> (e1, op : ts)
Run Code Online (Sandbox Code Playgroud)
T_Plus等是Token数据类型的成员,Plus,Minus等是BinOp的一部分,BinOpApp应用于两个操作数.我更新了Token和BinOpApp数据类型以处理Power(取幂)令牌.这是结果代码:
parseExpRec e1 (op : ts) =
let (e2, ts') = parsePrimExp ts in
case op of
T_Plus -> parseExpRec (BinOpApp Plus e1 e2) ts' …Run Code Online (Sandbox Code Playgroud) 我在Haskell中定义了一个Tree数据类型,并在一个关联的'size'方法中计算了树中元素的数量.这之前有用,但我更新了Tree数据类型以使用命名字段,如下面的定义:
data Tree a = Empty
| Leaf {value::a}
| Node {left :: (Tree a), value :: a, right :: (Tree a)}
deriving (Eq, Ord, Show)
Run Code Online (Sandbox Code Playgroud)
我发现(通过在GHCi中玩游戏)我可以使用函数(左n)访问命名字段.但是,当我尝试使用此功能时,我收到一个错误:
size :: Tree a -> Int
size Empty = 0
size (Leaf l) = 1
size (Node n) = size (left n) + 1 + size (right n)
Run Code Online (Sandbox Code Playgroud)
GHCi简单地说"不在范围内:左边"和等同于右边.Tree定义位于名为Tree的模块中,大小定义位于名为Main的模块中,但是对于非命名字段,从Tree数据类型访问变量时,我从未遇到过范围问题.
我有一个搜索树,定义为:
data (Ord a) => Stree a = Null | Fork (Stree a) a (Stree a) deriving Show
Run Code Online (Sandbox Code Playgroud)
我必须定义两个函数,mapStree:
mapStree :: (Ord b, Ord a) => (a -> b) -> Stree a -> Stree b
Run Code Online (Sandbox Code Playgroud)
和foldStree:
foldStree :: (Ord a) => (b -> a -> b -> b) -> b -> Stree a -> b
Run Code Online (Sandbox Code Playgroud)
我不完全了解发生了什么,也不知道该怎么做.