我正在尝试在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) 我正在尝试创建一个基本函数来测试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 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) 真的,我想找出一个更简单的解决方案,用一个单一的功能点免费组成一个带有拉链的折叠.
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) 举个例子,我试图在一个函数中定义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中定义自然数乘法,并继续得到下面的错误(对应于下面的第二个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中通过大小写紧凑地写入多个定义,而不必重复输入参数以外的完全相同的语法?到目前为止,我能想象的唯一可行解决方案是宏观.
下面是定义二进制最大和最小函数的示例.我们能压缩吗?
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)