小编War*_*lan的帖子

如何在Haskell中编写lisp解析器?

我正在尝试在haskell中编写一个lisp解释器,受到Norvig在Python中的启发(http://norvig.com/lispy.html).我有一个成功的标记器,如果需要我可以链接到它.在这里,它输出正确的代码到Norvig的Python标记器.

program = "(begin (define r 10) (* pi (* r r)))"
astTokenized = tokenize program
astTokenized == ["(","begin","(","define","r","10",")","(","*","pi","(","*","r","r",")",")",")"]
Run Code Online (Sandbox Code Playgroud)

这里我定义了我的抽象语法树数据类型,虽然我知道它已经有一些隐式错误,因为它没有包含在列表中.

data Ast x = Val x | Node [Ast x] deriving (Show)
Run Code Online (Sandbox Code Playgroud)

这是我的第一次尝试:

parse :: [[Char]] -> [Ast [Char]]
parse (x:xs)
  | x == "(" = [Node (parse xs)]
  | x == ")" = []
  | otherwise = (Val x) : parse xs
Run Code Online (Sandbox Code Playgroud)

希望,除了它在第一个')之后终止.

Prelude> parse astTokenized
[Node [Val "begin",Node [Val "define",Val "r",Val "10"]]]
Run Code Online (Sandbox Code Playgroud)

这里我改变了[]的基本情况,并调整了')'的条件,因此它将解析整个输入终止,但它现在只创建一个更深的树,因此无法正确分支.

parse [] = …
Run Code Online (Sandbox Code Playgroud)

parsing haskell compilation

5
推荐指数
1
解决办法
409
查看次数

如何正确定义Haskell函数isPrime?

我正在尝试创建一个基本函数来测试Haskell中整数的素数.我有一些代码可以在临时意义上工作,但在我尝试将其传递给函数时会继续收到错误消息.请注意,我正在GHCi中直接编写定义,使用:{:}.

我们的想法是创建一个N modulo {所有整数直到舍入sqrt(N)}的列表,然后测试结果列表中除初始索引之外的零.以下四个功能都有效:

rndRoot :: (Floating a, Integral c, RealFrac a) => a -> c
rndRoot = round . sqrt

oneToRndRoot :: (Floating a, Integral t, RealFrac a) => a -> [t]
oneToRndRoot x = [1..rndRoot(x)]

modulo x y
  | n < 0 = x
  | otherwise = modulo n y
  where n = x - y

mapMod x = map (modulo x)
Run Code Online (Sandbox Code Playgroud)

这也有效:

mapMod 49 (oneToRndRoot 49)
Run Code Online (Sandbox Code Playgroud)

然而,虽然repl接受这个定义而没有抱怨......

mapModToRndRoot x = mapMod x $ …
Run Code Online (Sandbox Code Playgroud)

haskell discrete-mathematics number-theory

4
推荐指数
1
解决办法
232
查看次数

如何使用Pragma依赖关系在ghci中正确定义数据类型?

我正在尝试在Haskell Map for Trees中的 hammar答案中定义一个Tree类型的fmap

他的定义来自functor,它使用了pragma,我只是模糊地熟悉它.他的定义是

{-# LANGUAGE DeriveFunctor #-}
data Tree a = Leaf a | Node (Tree a) (Tree a)
    deriving (Functor, Show)
Run Code Online (Sandbox Code Playgroud)

我无法在GHCI中使用pragma和定义.以下是我的三次错误尝试,我将不胜感激任何反馈!

第一次尝试:

Prelude> {-# LANGUAGE DeriveFunctor #-}
Prelude> data Tree a = Leaf a | Node (Tree a) (Tree a)
Prelude>     deriving (Functor, Show)
<interactive>:30:5: parse error on input ‘deriving’
Run Code Online (Sandbox Code Playgroud)

第二次尝试:

Prelude> {-# LANGUAGE DeriveFunctor #-}
Prelude> data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Functor, Show)
<interactive>:32:57:
    Can't …
Run Code Online (Sandbox Code Playgroud)

haskell ghci

3
推荐指数
1
解决办法
77
查看次数

如何在Haskell中定义dot产品是一种无点样式?

真的,我想找出一个更简单的解决方案,用一个单一的功能点免费组成一个带有拉链的折叠.

zWMult :: Num c => [c] -> [c] -> [c]
zWMult = zipWith (*)

foldPl0 :: Num c => [c] -> c
foldPl0 = foldl (+) 0
Run Code Online (Sandbox Code Playgroud)

当我使用争论时,我得到了正确的解决方案

dPr x y = foldPl0 (zWMult x y)
dPr x y = foldPl0 $ zWMult x y
Run Code Online (Sandbox Code Playgroud)

但是不知道如何在没有论据的情况下自然地组成这些.这两个都失败了:

Prelude> :{
Prelude| let dPr1 :: Num c => [c] -> [c] -> c
Prelude|     dPr1 = fPl0 $ zWMult
Prelude| :}

<interactive>:171:19:
Couldn't match expected type ‘[[c] -> [c] -> c]’
            with …
Run Code Online (Sandbox Code Playgroud)

haskell linear-algebra

2
推荐指数
1
解决办法
229
查看次数

如何将"quot"正确定义为单个函数?

举个例子,我试图在一个函数中定义quot.我没有附加额外的参数(在这种情况下是一个计数器),我很难看到如何做到这一点.

quot x y n
  | x < y = n
  | otherwise = quot (x-y) y (n+1)

quot0 x y = x y 0
Run Code Online (Sandbox Code Playgroud)

我多次遇到这个问题并继续使用这个临时解决方案,而我知道必须有一种简单的方法来隐式地合并n.

haskell

1
推荐指数
2
解决办法
108
查看次数

如何在Haskell中交换定义自然数的乘法?

我试图在Haskell中定义自然数乘法,并继续得到下面的错误(对应于下面的第二个natMult定义).

Prelude> natMult (S (S Z)) (S (S Z))
*** Exception: <interactive>:(4,5)-(5,45): Non-exhaustive patterns in function natPlus
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

data Nat = Z | S Nat deriving (Show)

natPlus :: Nat -> Nat -> Nat
natPlus Z a = a
natPlus (S a) (S b) = natPlus a (S (S b))
Run Code Online (Sandbox Code Playgroud)

经过一些修修补补后,我意识到这个定义工作正常,而下面的第二个定义则被打破了.唯一的区别是natPlus的输入参数的顺序.

-- works fine
natMult :: Nat -> Nat -> Nat
natMult Z a = Z
natMult (S a) b = natPlus (natMult a b) b

-- gives gives the …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

1
推荐指数
1
解决办法
203
查看次数

是否可以在haskell中使用参数化定义?

有没有办法在haskell中通过大小写紧凑地写入多个定义,而不必重复输入参数以外的完全相同的语法?到目前为止,我能想象的唯一可行解决方案是宏观.

下面是定义二进制最大和最小函数的示例.我们能压缩吗?

max' x y
  | x > y = x
  | otherwise = y

min' x y
  | x < y = x
  | otherwise = y
Run Code Online (Sandbox Code Playgroud)

变成类似的东西

(max',min') x y
  | x (>,<) y = x
  | otherwise = y
Run Code Online (Sandbox Code Playgroud)

编辑:

我知道这可以让我们对"脾气暴躁的脸"进行参数化,但似乎仍然可以有更简洁的形式.

maxmin x y f
  | f x y = x
  | otherwise = y

max' x y = maxmin x y (>)
min' x y = maxmin x y (<)
Run Code Online (Sandbox Code Playgroud)

haskell

1
推荐指数
1
解决办法
48
查看次数