通过运算符关联性和优先级,我发现了以下内容:
infixr 0 $
infixl 1 &
infixl 4 <$>
infixl 1 <&>
Run Code Online (Sandbox Code Playgroud)
这看起来很奇怪.&并且<&>具有相同的优先级,但$并<$>不仅有广泛不同的优先级,而且在相关联的不同方向.
这有什么好的理由,还是只是一个历史性的疣?如果这是一个历史性的疣,你会怎样改变它?
Base 包含许多类型级别布尔操作的类型系列,如下所示:
https://hackage.haskell.org/package/base-4.8.2.0/docs/Data-Type-Bool.html
但是,指向True和False仅引用数据构造函数的链接,而Bool不是类型本身,因此可能它们不能用于类型级操作,因为它们是值,而不是类型.
有人可以解释这里发生了什么,我在哪里可以找到类型级定义?
我正在为我创建的数据类型编写一个"附加"函数(基本上处理"流").但是,这种数据类型有12种不同的构造函数,处理不同类型的"流",例如,无限,空,固定长度,可变长度,已经附加等.
输入类型和输出类型之间的逻辑有点复杂但并非如此令人难以置信.
我考虑过两种方法:
我知道第二种方法更难以维护,但忽视这一点,GHC会发现第二种方法更容易优化吗?如果它可以使用简单的跳转表(或者可能是两个跳转表)进行第二种方法,我怀疑它会更快.但是,如果它进行线性检查,它将会慢得多.
GHC是否将模式匹配(甚至非常大的匹配)优化为恒定时间跳转表?
考虑具有以下(伪)签名的"组合"函数:
(a1 -> a2 -> ... -> an -> r) ->
(s -> ai) ->
a1 -> a2 -> ... -> ai -> ... an -> r
where i in [1..n]
Run Code Online (Sandbox Code Playgroud)
当然我们不能在Haskell中编写上面的内容,但这是一个具体的例子:
f4change3 ::
(a1 -> a2 -> a3 -> a4 -> r) ->
(s -> a3) ->
a1 -> a2 -> s -> a4 -> r
f4change3 f g x1 x2 x3 x4 = f x1 x2 (g x3) x4
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,narity的每个函数都有一组函数n,因此我们需要的函数数量与arity呈二次方式增长.
我可以写出我需要的那些,但首先,我不想重新发明轮子,所以很高兴知道库是否已经完成了这个.但是,虽然我几乎没有使用镜头,但我已经阅读了一些关于它们的内容,这种问题似乎正好在他们的盟友身上,但我不确定该怎么做.如果可能的话,一些示例代码会很棒.
有没有办法写一个约束:
C t1 t2 :: Constraint
Run Code Online (Sandbox Code Playgroud)
如果t2匹配,它"满足"(是正确的词)t1.
例如:
C (forall a. Num a => a -> a -> a) (forall a. Num a => a -> a -> a) -- good
C (forall a. Num a => a -> a -> a) (Int -> Int -> Int) -- good
C (forall a. Num a => a -> a -> a) (Bool -> Bool -> Bool) -- fails
C (Int -> Int -> Int) (forall a. Num …Run Code Online (Sandbox Code Playgroud) 让我说我有一个像这样的语言的GADT(我的实际语言要复杂得多,大约50个构造函数,但这是一个简化的例子):
data Expr t where
Add :: Expr t -> Expr t -> Expr t
Sub :: Expr t -> Expr t -> Expr t
Mult :: Expr t -> Expr t -> Expr t
Negate :: Expr t -> Expr t
Abs :: Expr t -> Expr t
Scalar :: t -> Expr t
Run Code Online (Sandbox Code Playgroud)
现在让我们定义另一种数据类型:
data BinOpT = AddOp | SubOp | MultOp
Run Code Online (Sandbox Code Playgroud)
另外,假设我有以下功能:
stringBinOp :: BinOpT -> String
stringBinOp AddOp = "+"
stringBinOp SubOp = "-"
stringBinOp MultOp …Run Code Online (Sandbox Code Playgroud) 我粗略想要实现以下目标:
f :: a -> a
g :: b -> b
h :: Typeable t => t -> Maybe t
h x = case x of
(x is of type a) -> Just (f x)
(x is of type b) -> Just (g x)
_ -> Nothing
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用此签名编写一个函数,而不使用clone()或分配新的向量:
fn mapVec(f: Fn(T) -> T, x: Vec<T>) -> Vec<T>
Run Code Online (Sandbox Code Playgroud)
在我看来,这似乎是可行的。对于中的每个元素x,我们将其传递给f,并f获得所有权。然后,我们产生一个返回值,然后,作为f已传递值的所有权,如果有必要,它将销毁它。然后,我们将返回值放回向量中。拥有的所有权后x,我们可以对其进行修改,然后将其返回给调用方。
我的尝试如下:
for e in x.iter_mut() {
*e = f(e);
}
return x;
Run Code Online (Sandbox Code Playgroud)
但不幸的是f期望一个T,而不是一个&mut T。
我不想将其签名更改mapVec为例如使用可变函数,如果可能的话,我希望它看起来像是一个外部纯函数,只是利用内部的变异,因为我们可以摆脱它,因为调用者已将对象的所有权传递给我们。
考虑以下:
module MyModule (
A(FortyTwo), -- Note we don't expose PrivateA
B(P) -- Nor PrivateB
) where
pattern FortyTwo = A 42
newtype A = PrivateA Int
data B = PrivateB Int Int
pattern P :: Int -> A -> B
Run Code Online (Sandbox Code Playgroud)
我怎样才能写模式P?
基本上我可以说:
f :: B -> String
f (P 2 FortyTwo) = "The meaning of life"
Run Code Online (Sandbox Code Playgroud)
也就是说,能够在不引用私有构造函数的情况PrivateA下PrivateB直接在定义它们的模块外部进行模式匹配。