这个问题与这篇文章有关:Understanding do notation for simple Reader monad: a <- (*2), b <- (+10), return (a+b)
我不在乎一种语言是否难以理解,如果它有望解决一些易于理解的语言给我们带来的问题。我被承诺在 Haskell(和其他函数式语言)中不可能改变状态是一个游戏规则改变者,我确实相信这一点。我的代码中有太多与状态相关的错误,我完全同意这篇文章,即在 OOP 语言中对对象的交互进行推理几乎是不可能的,因为它们可以改变状态,因此为了推理代码,我们应该考虑这些状态的所有可能排列。
但是,我发现对 Haskell monad 的推理也非常困难。正如您在我链接的问题的答案中所见,我们需要一个大图来理解 do 符号的 3 行。>>=为了理解代码,我总是打开stackit.io手动去糖化do符号并一步一步地编写do符号的应用程序。
这个问题或多或少是这样的:在大多数情况下,当我们有S a >>= f我们必须展开a从S并应用f它。然而,f实际上在形式中或多或少是另一回事S a >>= g,我们也必须解开等等。人脑不是那样工作的,我们不能轻易地把这些东西应用到头脑中然后停下来,把它们放在大脑的堆栈中,然后继续应用剩下的东西,>>=直到我们到达终点。当到达终点时,我们将所有这些东西存储在大脑的堆栈中并将它们粘合在一起。
因此,我一定是做错了什么。必须有一种简单的方法来理解>>=大脑中的“成分”。我知道 do 表示法非常简单,但我只能将其视为一种轻松编写>>=作文的方法。当我看到do符号时,我只是将它翻译成一堆 >>=. 我不认为它是理解代码的一种单独方式。如果有办法,我希望有人告诉我。
所以问题是:如何阅读do符号?
我有一个给定的类型
type Foo = Either (Bool, ()) (Maybe Ordering)
Run Code Online (Sandbox Code Playgroud)
我知道该类型Bool有两个不同的值:True和False。
假设,以下类型是否正确:
type Foo = Either (Bool, ()) (Maybe Ordering)
Run Code Online (Sandbox Code Playgroud)
2+2+1+2+3 = 10考虑到其他类型的构建方式,具有不同的值:
data Either a b = Left a | Right b
data Maybe a = Just a | Nothing
data Ordering = EQ | LT | GT
Run Code Online (Sandbox Code Playgroud) 如果我在没有自定义包的 REPL 中运行它,以下来自 Paul G 的OnLisp 的代码工作正常。当我定义一个包并与它一起使用时(in-package :mypackage)它不起作用——它总是t在case语句中采用这种情况:
(defun run-node (name)
(let ((n (gethash name *nodes*)))
(cond ((node-yes n)
(format t "~A~%>> " (node-contents n))
(case (read)
(yes (run-node (node-yes n))) ; never hits this in package
(t (run-node (node-no n)))))
(t (node-contents n)))))
Run Code Online (Sandbox Code Playgroud) 不是在 Lisp 中创建新列表list的关键字,但在 Lisp 中可以调用一个参数list。我认为大多数编程语言(如 Java 或 C++)中的关键字不能用于参数 名称,Lisp 中是否有特殊原因可以使用?
在为MIT/GNU Scheme (rel 9.2 ) 中的odd和even函数开发经典练习代码时,我遇到了一个问题,即我的代码不会因大整数值而终止。首先,我测试了以下代码,它处理正值和负值:
(define error-message-number "Error. x must be a number")
(define odd?
(lambda (x)
(cond
((not (integer? x)) error-message-number)
((= x 0) #f)
((< x 0) (even? (+ x 1))) ;for negatives
(else (even? (- x 1)))))) ;if number n is odd then n - 1 is even
(define even?
(lambda (x)
(cond
((not (integer? x)) error-message-number)
((= x 0) #t)
((< x 0) (odd? (+ x 1))) ;for negatives
(else …Run Code Online (Sandbox Code Playgroud) 我正在努力使用的 Haskell 函数具有以下类型
func1 :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
我不确定如何在实际实现中处理括号部分。我知道在这种情况下应该将一个函数传递到输入中。
(Integer -> Integer -> Integer)
fibs = 1:1:[x+y|x <- fibs, y <- tail fibs]
Run Code Online (Sandbox Code Playgroud)
返回
[1,1,2,3,4,5,6,7,8,9]
fibs = 1:1:[x+y|(x, y) <- zip fibs (tail fibs)]
Run Code Online (Sandbox Code Playgroud)
返回
[1,1,2,3,5,8,13,21,34,55...]
我是 Haskell 的初学者,我想知道是否可以打印给定列表的单个元素。我尝试解决这个问题,但失败了。这是代码:
main :: IO()
main = do
let list = [1,2,3]
let size = length list
let temp = print_elem list size
print temp
print_elem :: [Int] -> Int -> Int
print_elem xs x = do
let size = length xs
let idx = size - x
let element = xs !! idx
putStr (show element)
putStr(" ")
let dummy = print_elem (xs (x-1))
return " "
Run Code Online (Sandbox Code Playgroud)
我想打印这样的东西
1 2 3
Run Code Online (Sandbox Code Playgroud)
如果我只是使用putStr (show list)它会显示[1,2,3],我不想要那样。 …
我有一个函数,它返回从输入列表中找到的半个回文列表。如果我在一行上使用 if 语句但我想使用守卫,它会起作用。守卫给我一个解析错误。我阅读了很多给出这种错误的案例,但我没有弄清楚我的案例。这是代码:
palindromeHalfs :: [String] -> [String]
palindromeHalfs xs = map firstHalf (filter palindrome xs)
where
firstHalf :: String -> String
firstHalf ys | (length ys) `rem` 2 == 0 = take ((div (length ys 2)) ys
| otherwise = take ((div (length ys 2) + 1) ys
palindrome :: String -> Bool
palindrome str | str == reverse str = True
| otherwise = False
Run Code Online (Sandbox Code Playgroud)
和错误:
palindromeHalfs.hs:6:20: error: parse error on input `otherwise'
|
6 | | otherwise …Run Code Online (Sandbox Code Playgroud) 我正在用方案编码一个函数,但我收到一个“应用程序:不是过程;期望一个可以应用于参数的过程”错误。我假设我没有正确使用条件语句:
(define find-allocations
(lambda (n l)
(if (null? l)
'()
(cons ((if (<=(get-property (car l) 'capacity) n)
(cons (car l) (find-allocations (- n (get-property (car l) 'capacity)) (cdr l)))
'()))
(if (<=(get-property (car l) 'capacity) n)
(cons (car l) (find-allocations (n (cdr l))))
'())))))
Run Code Online (Sandbox Code Playgroud)
如果有人能指出我的错误,将不胜感激。
haskell ×6
scheme ×3
lisp ×2
racket ×2
types ×2
arguments ×1
common-lisp ×1
do-notation ×1
fibonacci ×1
function ×1
guard-clause ×1
io-monad ×1
list ×1
mit-scheme ×1
monads ×1
output ×1
package ×1
parse-error ×1
recursion ×1
sbcl ×1
user-input ×1