是否有任何好的教程从头开始在Haskell中为给定的语法编写解析器?
我发现:
但所有这些都使用了parsec库,虽然这可能对工业应用程序很有意思,但我特别在寻找没有使用复杂库的"自下而上"的例子.
我发现使用'基本'Haskell的唯一一个是: 使用一些非常外来的语法解析Haskell(很难区分程序的一部分或者只是'伪代码')并且没有明确的语法定义.
任何建议都非常感谢!
我正在尝试将C代码包含到一个简单的C++程序中,但我遇到了一个意想不到的问题 - 当我尝试编译程序时,g ++会出现以下错误:
/tmp/cccYLHsB.o: In function `main':
test1.cpp:(.text+0x11): undefined reference to `add'
Run Code Online (Sandbox Code Playgroud)
我搜索了一个解决方案并找到了本教程:
http://www.parashift.com/c++-faq/overview-mixing-langs.html
我的程序似乎没什么区别所以我有点迷失了......
我的C++程序如下所示:
test1.ccp
#include <iostream>
using namespace std;
extern "C" {
#include "sample1.h"
}
int main(void)
{
int x= add(3);
cout << "the current value of x is " << x << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
sample1标头和函数如下所示:
sample1.h
#include <stdio.h>
double add(const double a);
Run Code Online (Sandbox Code Playgroud)
sample1.c
#include "sample1.h"
double add(const double a)
{
printf("Hello World\n");
return a + a;
}
Run Code Online (Sandbox Code Playgroud)
对于编译,我首先使用g ++编译test1.o,使用gcc编译sample1.o(尝试使用g ++但没有区别)
g++ -c test1.cpp …Run Code Online (Sandbox Code Playgroud) 我在lambda演算中对这个名称的类型进行了参数表示:
{-# LANGUAGE DeriveFunctor #-}
data Lambda a = Var a | App (Lambda a) (Lambda a) | Lam a (Lambda a)
deriving Functor
Run Code Online (Sandbox Code Playgroud)
我想知道是否Lambda可以成为monad的一个实例?我认为以下内容可能适用于以下内容join:
joinT :: Lambda (Lambda a) -> Lambda a
joinT (Var a) = a
joinT (fun `App` arg) = joinT fun `App` joinT arg
joinT (Lam n body) = ?
Run Code Online (Sandbox Code Playgroud)
对于第三种情况,我完全没有线索...但它应该是可能的 - 这个无名的lambda术语表示,取自De Bruijn Notation作为嵌套数据类型,是Monad的一个实例(Maybe用于区分绑定和自由这个表示中的变量):
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DeriveFunctor #-}
data Expr a
= V …Run Code Online (Sandbox Code Playgroud) 您好Haskell社区,
当我尝试构建我的第一个更大的项目时,我是Haskell的新手并遇到了一个问题.
这是问题的最小例子(我正在使用cabal来构建).
这是一个简单模块的目录结构:
FooMod1
|- FooMod1.cabal
|- Setup.hs
|- src
|- FooMod1.hs
|- FooMod1
|- C1.hs
|- T1.hs
Run Code Online (Sandbox Code Playgroud)
FooMod1.hs的来源:
module FooMod1 (
C1(..) ,
T1(..) ,
) where
import FooMod1.C1
import FooMod1.T1
Run Code Online (Sandbox Code Playgroud)
C1.hs的来源:
module FooMod1.C1 (
C1(..)
) where
class C1 a where
c1FooFun :: a -> IO ()
Run Code Online (Sandbox Code Playgroud)
T1.hs的来源:
module FooMod1.T1 (
T1(..)
) where
import FooMod1.C1
data T1 = T1 deriving(Show)
instance C1 T1 where
c1FooFun T1 = putStrLn "c1FooFun from T1"
Run Code Online (Sandbox Code Playgroud)
cabal文件的来源:
Name: FooMod1
Version: 0.0.1 …Run Code Online (Sandbox Code Playgroud) 我试着Control.Monad.Writer像这样导入模块:
import Control.Monad.Writer
Run Code Online (Sandbox Code Playgroud)
ghc 版本7.4.1给出以下错误:
Ambiguous module name `Control.Monad.Writer':
it was found in multiple packages: monads-tf-0.1.0.1 mtl-2.1.1
Run Code Online (Sandbox Code Playgroud)
有类似的问题和解决方法问题在这里.
尽管在这个帖子中给出了解决方案,但我的问题是:
这是cabal和ghc的标准配置吗?
- 如果是这样的话:默认情况下模块是否有两个包的原因?
- 如果不是:发生了什么(可能有)并且可以撤消?
如果这很重要:我正在使用Debian 7.3 wheezy并安装了haskell-platform软件包.此外,我使用安装了一些包cabal install.
提前谢谢了!
我想在Prolog中使用DCG解析逻辑表达式。
逻辑术语表示为列表,例如['x','&&','y'],x ? y结果应为解析树and(X,Y)(X并且Y是未分配的Prolog变量)。
我实现了它,一切都按预期工作,但是我有一个问题:
我不知道如何解析变量'x'并'y'获取真实的Prolog变量X以及Y以后的真值分配。
我尝试了以下规则变体:
v(X) --> [X].:
这当然不起作用,只会返回and('x','y')。
但是我是否可以用Prolog变量统一替换本术语中的逻辑变量?我知道该谓词term_to_atom(它被提议作为类似问题的解决方案),但是我认为它不能在此处用于实现所需的结果。
v(Y) --> [X], {nonvar(Y)}.:
这的确会返回一个未绑定的变量,但是每次都会返回一个新变量,即使逻辑变量('x','y',...)已经包含在术语中,因此
也会['X','&&','X']被评估and(X,Y)为不是期望的结果。
是否有任何优雅或惯用的解决方案来解决这个问题?
提前谢谢了!
编辑:
这个问题的背景是我试图在Prolog中实现DPLL算法。我认为将逻辑术语直接解析为Prolog术语会很聪明,以便轻松使用Prolog回溯功能:
[x,'&&',y][G_123,'&&',G_456]现在具有“真实” Prolog变量)v找到一个分配,以使v(T) = t搜索空间耗尽。我对Prolog还是陌生的,老实说,我想不出更好的方法。我对更好的替代品非常感兴趣!(所以我有点半信半疑,这就是我想要的;-)非常感谢您到目前为止的支持...)
我的项目结构如下:
~/.../project_name
project_name.cabal
Setup.hs
src/
Main.hs
Data/
...
test/
MainTestSuite
...
Run Code Online (Sandbox Code Playgroud)
我(其中包括)以下几行project.cabal:
build-type: Simple
...
executable project_name
main-is: Main.hs
...
hs-source-dirs: src
Run Code Online (Sandbox Code Playgroud)
当我cabal configure(工作正常)然后cabal build收到错误消息:
cabal: can't find source for Setup in src, dist/build/autogen
Run Code Online (Sandbox Code Playgroud)
当我插入时它可以工作Source.hs,src但是对我来说似乎是一团糟,在其他项目中却从未见过,而其他项目Source.hs始终在项目根目录中。我如何cabal找到Source.hs?
Source.hs顺便说一句:无论如何,目的是什么?
是否有任何常用的方法甚至库来漂亮地打印(和解析)带有(二进制)运算符的语法树,并为其分配了关联性和优先级,以便结果使用尽可能少的括号?
以命题演算的公式为例:
data Formula
= Atom String
| Not (Formula)
| And (Formula) (Formula)
| Or (Formula) (Formula)
| Imp (Formula) (Formula)
Run Code Online (Sandbox Code Playgroud)
假定优先级为Imp< Or< And< Not(所以Not结合最),并且And,Or和Imp应关联到的权利; 所以例如Imp (And (Imp (Atom "A") (Atom "B")) (Atom "A")) (Atom "B")应该打印像(A -> B) /\ A -> B。
当然,这可以通过模式匹配来实现,但这很繁琐而且非常不愉快。我正在从Coq证明助理中寻找与此符号类似的简单内容:
Notation "A /\ B" := (and A B) (at level 80, right associativity).
Run Code Online (Sandbox Code Playgroud)
生成一个解析器和一个漂亮的打印机。
我正在通过Richard Bird和Ross Paterson 的文章De Bruijn表示法作为嵌套数据类型.在一个点上,定义了一个术语的折叠操作:
infixl 9 :@
data Expr a =
Var a
| (Expr a) :@ (Expr a)
| Lam (Expr (Maybe a)
foldT ::
(forall a. a -> n a) ->
(forall a. n a -> n a -> n a) ->
(forall a. n (Maybe a) -> n a) ->
Expr b -> n b
foldT v _ _ (Var x) = v x
foldT v a l (fun :@ arg) = a (foldT …Run Code Online (Sandbox Code Playgroud) 为什么以下尝试在列表推导中进行模式匹配不起作用?
示例:在术语数据类型中同时替换原子.
数据类型:
data Term a
= Atom a
| Compound (Term a) (Term a)
deriving Show
Run Code Online (Sandbox Code Playgroud)
原子的替换算法(选择第一个匹配的替换,如果有的话,忽略其余的):
subs :: [(Term a, Term a)] -> Term a -> Term a
subs subList term = case term of
atom@(Atom x) -> let substitutions =
[ s | s@(Atom x, _) <- subList ]
in if null substitutions
then atom
else snd . head $ substitutions
(Compound t1 t2) -> Compound (subs subList t1) (subs subList t2)
Run Code Online (Sandbox Code Playgroud)
一些测试数据:
subList = [((Atom 'a'), …Run Code Online (Sandbox Code Playgroud) 是否有一些相当于在r中表达let表达式?举个例子来看看这个简单的haskell代码:
let x = 1 in x + 1
Run Code Online (Sandbox Code Playgroud)
提前谢谢了.
我有以下形式的JSON日期数据:
{"date": "2015-04-12"}
Run Code Online (Sandbox Code Playgroud)
和相应的haskell类型:
data Date = Date {
year :: Int
, month :: Int
, day :: Int
}
Run Code Online (Sandbox Code Playgroud)
如何为Aeson库编写自定义FromJSON和ToJSON函数
?由于格式化,派生实例不起作用.