我试图弄清楚如何使用前缀表示法重写monadic计算(不是为了实际目标,仅用于研究),而是一个lambda看不到另一个参数的问题
给一个工作的例子
*Main> [1, 3, 4] >>= \x -> [x + 1, x - 1] >>= \y -> return (y*x)
[2,0,12,6,20,12]
Run Code Online (Sandbox Code Playgroud)
重写的那个显示错误没有看到其他lambda的参数
*Main> (>>=) ( (>>=) [1, 3, 4] (\x -> [x + 1, x - 1]) ) (\y -> return (y*x))
<interactive>:133:68: Not in scope: `x'
Run Code Online (Sandbox Code Playgroud)
但如果我让最后一个不使用它(通过用y代替x),计算就开始工作了
*Main> (>>=) ( (>>=) [1, 3, 4] (\x -> [x + 1, x - 1]) ) (\y -> return (y*y))
[4,0,16,4,25,9]
Run Code Online (Sandbox Code Playgroud)
那么技术上可能在前缀表示法中完全重写吗?或者访问其他lambdas参数的这个属性是中缀表示法独有的?
尽管多次阅读Scala样式指南 - 方法调用,但我已经对此感到困惑了一段时间.
我希望能够调用此方法
def foldRVL[A,B](l: List[A], z: B)(f: (A, B) => B) = //"Right-Via-Left"
l.reverse.foldLeft(z)((a, b) => f(b, a))
Run Code Online (Sandbox Code Playgroud)
使用这样的点符号List(1,2,3).foldRVL(0)(_ + _).
而不是这样的:foldRVL(List(1,2,3), 0)(_ + _).
此外,有时我看到的代码显示的方法实际上是在签名中采用零参数,或者比我预期的要少一个参数,并且仍然使用点符号正确地获取参数.这是如何运作的?我问这个,因为这些方法使用点符号,所以也许如果我写了类似的东西,我可以解决我的问题.
这是类型签名和filter函数的定义,从了解你是一个很好的Haskell!:
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' p (x:xs)
| p x = x : filter' p xs
| otherwise = filter' p xs
Run Code Online (Sandbox Code Playgroud)
书中的用法示例elem如下:
filter' (`elem` ['a'..'z']) "Hell0!"
Run Code Online (Sandbox Code Playgroud)
哪个回报:
"ell"
Run Code Online (Sandbox Code Playgroud)
在这个特定的例子中,是否有可能使用elem前缀函数而不是中缀函数作为谓词?
在更一般的意义上,是否有一种方法只提供第二个参数以部分应用前缀函数?
在此先感谢您的帮助!
在试图理解该类型的中缀运算符xfy并且yfx具有相同的优先级和顺序时,我看到只有四种组合.
运用
a = xfy right-associative
b = yfx left-associative
Run Code Online (Sandbox Code Playgroud)
有
aa e.g. 1 xfy 2 xfy 3 e.g. 1 ^ 2 ^ 3
ab e.g. 1 xfy 2 yfx 3
ba e.g. 1 yfx 2 xfy 3
bb e.g. 1 yfx 2 yfx 3 e.g. 1 - 2 - 3
Run Code Online (Sandbox Code Playgroud)
现在对于(xfy xfy)aa,运算符都是正确关联的.
对于(yfx yfx)bb,运营商都是左联盟.
但是对于(xfy yfx)ab ,(xfy)a运算符是右关联的,而(yfx)b运算符是左关联的.如果我理解正确,Prolog将评估为:
使用优先权500和x意义<和y意义 …
所以这不起作用:
take 50 iterate (* 2) 1
Run Code Online (Sandbox Code Playgroud)
因为它需要在第二个参数中使用括号.我的问题是为什么.
Haskell理所当然地看到了类型的差异:
Couldn't match expected type `[a0]'
with actual type (a1 -> a1) -> a1 -> [a1]'
Run Code Online (Sandbox Code Playgroud)
我的问题是:
1)似乎haskell首先尝试在迭代函数之前解析take 50函数.为什么haskell会这样做?在数学中,如果你有fgtwu(x),你首先评估你(x)然后再做其他事情.为什么haskell在这种情况下开始评估f?
2)Haskell足够聪明,可以检测出实际类型是:
(a1 -> a1) -> a1 -> [a1]
Run Code Online (Sandbox Code Playgroud)
现在,如果它看到这个函数的输出是[a1],一个与预期类型[a0]统一的类型,为什么haskell不统一呢?
3)为什么$运营商会解决这个问题?我知道:
($) :: (a -> b) -> a -> b
Run Code Online (Sandbox Code Playgroud)
所以这个操作符的基本操作就是"写FUNCTION $ ARGUMENT"并获得在该参数中计算的函数的值.在take 50案例中,类型是:
take 50 :: [a2]->[a2]
take 50 $ :: a->b
where a ~a2 and b~b2 then
take 50 $ :: [a2]->[a2]
Run Code Online (Sandbox Code Playgroud)
因此,基本上我处于与第一种情况相同的情况,不使用括号或$.这种情况是我需要一个类型[a2]的参数(haskell称之为[a0]但它是相同的.所以..为什么haskell统一[a2]与(a1 - > a1) - > a1 - > [a1]当我使用$但它没有当我不使用它?
haskell function infix-notation operator-precedence operator-keyword
我defpackage在Lisp中弄湿了脚,开始了一个可耻的开始,即一个我无法理解的错误.
下面的代码是尝试创建子语言以对向量执行中缀操作.我想将它用于涉及一些线性代数的项目.
我的代码的"肉"是parse-infix.此函数查找具有最高优先级的运算符,调用apply-op替换所述运算符及其操作数,operator (operand, operand)从而收缩列表,并迭代直到列表仅包含结果.支持的运算符是四个规则,相等(将结果绑定到Lisp符号)和向量连接.
这是代码,疣和所有:
(defpackage :infix
(:use :common-lisp)
(:export operator-list
operators
parse-infix
infix))
(in-package :infix)
(defun parse-input (a)
"Turns symbols into numbers as necessary while reading an expression"
(if (symbolp a) (symbol-value a) a))
;; Definition of structure containing data for one operator
(defmacro mapf (op type)
""
`(lambda (a b)
(map ,type #'(lambda (x y)
(funcall ,op x y)) (parse-input a) (parse-input b))))
(defstruct (operator
(:conc-name op-)
(:constructor op …Run Code Online (Sandbox Code Playgroud) 对于我的数据结构类,我必须使用 Python 3 创建一个基本的图形计算器。要求是我们必须使用一个基本的 Stack 类。用户以“中缀”形式输入方程,然后我应该将其转换为“后缀”以进行评估和绘图。我在使用中缀到后缀算法时遇到问题。我见过其他可以工作的算法,但我的教授希望它以某种方式完成。这是我到目前为止所拥有的:
def inFixToPostFix():
inFix = '3*(x+1)-2/2'
postFix = ''
s = Stack()
for c in inFix:
# if elif chain for anything that c can be
if c in "0123456789x":
postFix += c
elif c in "+-":
if s.isEmpty():
s.push(c)
elif s.top() =='(':
s.push(c)
elif c in "*/":
if s.isEmpty():
s.push(c)
elif s.top() in "+-(":
s.push(c)
elif c == "(":
s.push(c)
elif c == ")":
while s.top() is not '(':
postFix += s.pop()
s.pop()
else: …Run Code Online (Sandbox Code Playgroud) Kotlin编码约定,在使用中缀函数部分中说:
仅当函数作用于两个扮演类似角色的对象时,才将函数声明为中缀。好的例子:
and,to,zip. 不好的例子:add.如果方法改变了接收者对象,请勿将其声明为中缀。
我的第一个问题是:什么样的例子才是add坏榜样?
然后在基本类型的讨论中,它解释了按位运算符是“可以以中缀形式调用的命名函数”,并给出了这个示例(作为更大表达式的一部分):
(1 shl 2)
Run Code Online (Sandbox Code Playgroud)
在我看来,三个 Kotlin 移位操作(shl、shr和ushr)违反了编码约定。左操作数和右操作数根本不扮演类似的角色。左操作数是原始位模式,右操作数是位模式应移动的距离。
我在这里错过了什么吗?
我有一个 Common Lisp 阅读器宏来解析“或”关系的惰性/延迟声明,使用由管道符(“|”)分隔的中缀语法以及标准列表括号和关键字文字。考虑形式 (:a :b|:c) - 它表示一个 2 部分元组,其中第一个元素肯定是 :a,第二个元素是 :b 或 :c。例如,可以推断整个元组的有效形式是 (:a :b) 或 (:a :c)。
我已经有函数封装的逻辑来解构 read 宏之后的这些元组列表形式。但在阅读时,我需要解析像 :a|:b|:c 这样的形式,并用移除的管道标记它,比如 (:lazy-or :a :b :c)。中缀语法的使用纯粹是为了面向读者的形式;中缀形式是短暂的,会在阅读阶段立即被丢弃,取而代之的是用 :lazy-or 标记的等效合法 lisp 形式。
所以我制作了一个几乎可以正常工作的 read 宏,但目前需要在第一个 or-form 关键字元素之前使用一个额外的管道作为一种读者标志(我希望这不是必需的完全),并且它目前无法使用嵌套括号或拼接符号推断类似形式作为等效(如在算术中,2+(3*4)具有相同的运算顺序,等效形式,如2+3*4)。
宏(源自此处的“斜线阅读器”:http : //www.lispworks.com/documentation/HyperSpec/Body/f_rd_rd.htm):
(defun pipe-reader (stream char)
(declare (ignore char))
`(:lazy-or . ,(loop for dir = (read stream t nil t)
then (progn (read-char stream t nil t)
(read stream t nil t))
collect dir
while (eql …Run Code Online (Sandbox Code Playgroud) macros common-lisp infix-notation infix-operator reader-macro
我见过这样的 Haskell 代码:
infix 4 ~=
(~=) :: Double -> Double -> Bool
x ~= y = abs (x-y) < epsilon
where epsilon = 1 / 1000
Run Code Online (Sandbox Code Playgroud)
尽管我知道这段代码在做什么,但我想知道是什么infix 4意思。
infix-notation ×10
haskell ×4
common-lisp ×2
algorithm ×1
coding-style ×1
filter ×1
function ×1
iso-prolog ×1
kotlin ×1
macros ×1
operators ×1
package ×1
predicate ×1
prefix ×1
python-3.x ×1
reader-macro ×1
scala ×1
this ×1