小编Wil*_*ess的帖子

如何快速阅读 do 符号而不转换为 >>= 组合?

这个问题与这篇文章有关: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我们必须展开aS并应用f它。然而,f实际上在形式中或多或少是另一回事S a >>= g,我们也必须解开等等。人脑不是那样工作的,我们不能轻易地把这些东西应用到头脑中然后停下来,把它们放在大脑的堆栈中,然后继续应用剩下的东西,>>=直到我们到达终点。当到达终点时,我们将所有这些东西存储在大脑的堆栈中并将它们粘合在一起。

因此,我一定是做错了什么。必须有一种简单的方法来理解>>=大脑中的“成分”。我知道 do 表示法非常简单,但我只能将其视为一种轻松编写>>=作文的方法。当我看到do符号时,我只是将它翻译成一堆 >>=. 我不认为它是理解代码的一种单独方式。如果有办法,我希望有人告诉我。

所以问题是:如何阅读do符号?

monads haskell functional-programming do-notation

0
推荐指数
2
解决办法
318
查看次数

该类型有多少个不同的值?

我有一个给定的类型

type Foo = Either (Bool, ()) (Maybe Ordering)
Run Code Online (Sandbox Code Playgroud)

我知道该类型Bool有两个不同的值:TrueFalse

假设,以下类型是否正确:

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)

haskell types

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

带有自定义包的 `read` 上的 Common Lisp `case`

如果我在没有自定义包的 REPL 中运行它,以下来自 Paul G 的OnLisp 的代码工作正常。当我定义一个包并与它一起使用时(in-package :mypackage)它不起作用——它总是tcase语句中采用这种情况:

(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 user-input sbcl common-lisp package

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

在 Lisp/Racket/Scheme 中,怎么可能有一个名为“list”的参数?

不是在 Lisp 中创建新列表list关键字,但在 Lisp 中可以调用一个参数list。我认为大多数编程语言(如 Java 或 C++)中的关键字不能用于参数 名称,Lisp 中是否有特殊原因可以使用?

lisp scheme arguments function-call racket

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

在Scheme中的相互递归中获得尾调用优化

在为MIT/GNU Scheme (rel 9.2 ) 中的oddeven函数开发经典练习代码时,我遇到了一个问题,即我的代码不会因大整数值而终止。首先,我测试了以下代码,它处理正值和负值:

(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)

recursion scheme tail-recursion mutual-recursion mit-scheme

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

Haskell 复杂函数类型

我正在努力使用的 Haskell 函数具有以下类型

func1 :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer

我不确定如何在实际实现中处理括号部分。我知道在这种情况下应该将一个函数传递到输入中。 (Integer -> Integer -> Integer)

haskell types function

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

为什么下面两个表达式有不同的结果

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 list-comprehension list fibonacci

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

如何在 Haskell 中打印列表的单个元素?

我是 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],我不想要那样。 …

haskell functional-programming output io-monad

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

如何解决输入“否则”的 Haskell 解析错误

我有一个函数,它返回从输入列表中找到的半个回文列表。如果我在一行上使用 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)

haskell parse-error guard-clause

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

方案 - 应用程序:不是程序错误

我正在用方案编码一个函数,但我收到一个“应用程序:不是过程;期望一个可以应用于参数的过程”错误。我假设我没有正确使用条件语句:

(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)

如果有人能指出我的错误,将不胜感激。

scheme racket non-procedure-application

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