Answers:
在Husk中,测试某些属性的输入的函数通常会在真实情况下返回有意义的结果,因为任何正整数都是真实的。
例子:
≠ Numbers: Absolute difference
Chars: Absolute difference of code points
Lists: First Index where the differ
Comparisons <, >, ≤, ≥:
For strict comparisons:
Numbers,Chars: max 0 (the appropriate difference¹)
Lists: The first index where the comparison between the two lists is true
For non-strict comparisons:
Numbers,Chars: max 0 (the appropriate difference + 1)
Lists: Either the result of the strict comparison or, if they are equal,
the length of the list + 1
ṗ Index into the list of prime numbers
V The index of the first element for which the condition is true
€ The first index of that element/substring in the list
£ Works like €
& Given two arguments of the same type will return the second argument if false,
otherwise will return the first argument
| Given two arguments of the same type will return the second argument if true,
otherwise will return the first argument
¦ Return the quotient if divisibility holds
Λ,E,Ë Will all return length+1 in truthy cases
Char predicates:
□,±,√,D,½ will each return the codepoint of its argument on truthy cases
¹ 适当的差异是指字符代码点的差异。它也指参数顺序。即对于<x y,将是x-y
您可能已经知道, [₀-₉]+|[₀-₉]正则表达式的语法可以调用与当前所在行不同的行。
如果希望将在特定行上定义的函数作为下表中多个函数的自变量调用,或者将其作为下面一个或多个函数的自变量,则本技巧特别有用。
功能表:
+----------+----------+
|Index |Function |
+----------+----------+
|1 |´ (argdup)|
+----------+----------+
|2 |` (flip) |
+----------+----------+
|3 |m (map) |
+----------+----------+
|4 |z (zip) |
+----------+----------+
|5 |S (hook) |
+----------+----------+
代码中的行从上到下分别标有从0开始的索引。如果M <N,其中M是标签,N是代码中的行数,则标签仅表示在M行定义的函数。如果N≤M <N * 6,则表示上表中索引为⌊M÷N⌋的函数,并将在行M mod N处定义的函数作为其第一个参数。如果N * 6≤M,则会产生索引错误。
Γ内置的主要用途(Γ称为列表上的模式匹配或列表解构)是将列表分为头和尾,并对它们应用二进制函数。这对应于Haskell模式匹配惯用法
f (x : xs) = <something>
f [] = <something else>
其中<something>是含有表达x,xs并且可能f。共有4个重载Γ,每个重载都略有不同。
list第一个重载,list需要一个值a和一个二进制函数f。它返回一个接受列表的新函数,a如果它为空,则返回,如果它为非空,则f在头和尾调用。例如,Γ_1€获取一个列表,-1如果它为空,则返回,如果不是,则返回尾部第一个元素的第一次出现的索引。
listN第二次重载listN类似于list,不同之处在于,它a被省略,并使用返回类型的默认值代替。例如,Γ€等价于Γ0€,因为默认数字值为0。
实际上,listN与相比,它的使用频率更高list,因为默认值无关紧要,或者正是您所需要的。一个常见的模式是Γ~αβγ,其中αβγ三个功能;这适用β于第一个元素和γ尾部,并将结果与组合α。例如在此答案中使用了它。其它图案包括Γo:α用于施加α仅仅与第一元件,和Γ·:mα用于施加α到除了第一所有元素。在此答案中使用了后者。
listF第三重载涉及更多。像一样list,它接受一个值a和一个函数f,并返回一个g接受列表的新函数。但是,这一次f需要一个额外的函数参数,该参数g本身就是参数,并且可以在任何值(包括但不限于输入列表的尾部)上调用它。这意味着在列表上listF实现通用的递归方案。
listF并不经常使用,因为使用list/的显式递归listN通常具有相同的长度或更短的长度,如在此答案中。
listNFlistNF是listF什么listN是list:输入a被省略,返回类型的默认值来代替。在极少数情况下,它可能比右折短,例如在此答案中。
作为的递归版本的一个示例Γ,该函数Γλ·:o⁰↔按第一,最后,第二,倒数第二,第三,倒数第三的顺序对列表进行随机排序。
在线尝试!
该函数f是显式lambda λ·:o⁰↔,其参数⁰是整个函数。要做的f是用反转尾巴↔,然后用递归调用main函数o⁰,最后用固定头·:。当然,Γ·:o₀↔它要短一个字节,但是如果该行包含的内容不是此函数,则该行不起作用。
假设您有一个整数X的列表,并且想要计算X中大于length(X)的元素总数。满足谓词计数元件与更高阶函数来完成#,但这里的谓词(即大于长度(X)取决于)X。解决方案是将组合器Ṡ应用于#和o>L检查列表是否短于数字的函数。在功能方面Ṡ#o>L,列表X传递到o>L,部分应用函数传递给#,并且X被提供给#作为第二个参数。
通常,如果α是高阶函数,β二进制函数和γ一元函数,Ṡαβ则等效于Haskell伪代码
\x -> α (\y -> β x y) x
§αβγ 相当于
\x -> α (\y -> β x y) (γ x)
和~αβγ相当于
\x y -> α (\z -> β x z) (γ y)
只要类型匹配。
作为另一个具体示例,§►δṁ≠P找到一个列表X的排列,该排列将绝对差的总和最大化为X的对应值(δṁ≠使用绝对差压缩两个列表并求和)。
Husk不像Haskell那样严格,例如,当您尝试获取last空列表的元素时就会遇到麻烦。为此,它使用预定义的值,这是默认值的最大值和最小值的列表:
.------------------------------------.---------------.----------.-------.
| Type (X and Y are placeholders) | default (def) | max | min |
|------------------------------------|---------------|----------|-------|
| Character (C) | ' ' | \1114111 | \NUL |
| Numbers (N) | 0 | Inf | -Inf |
| List of X (LX) | [] | ∞ max | [] | *
| Function :: X -> Y | const (def Y) | n/a | n/a |
'------------------------------------'---------------'----------'-------'
*此处∞代表相应最大值的无限列表(请参阅下面的示例)
注意:对于元组(X,Y),它将分别使用每个组件的值。
虽然最大值和最小值仅用于 ▲▼空列表(例如,husk -u "▼" "[]:LLN"将返回的无限列表Inf),但在一些地方使用了默认值:
F和Ḟ)Θ)r)失败时←→)或索引一个(!)Γ空列表上的)►或◄在空列表上