这样定义,我们既不做++x++也不做++x--.但另一方面,无论是(++x)++和(++x)--是有用的表达式:(++x)++增量x由两个并返回"中间"的价值,而(++x)--实质上等同于x+1而是完全避免了打电话operator+,这是非常有用的时候.
那么为什么没有定义的优先级++x++自动扩展到(++x)++而不是++(x++)?对于后者有一些隐藏的含义,我不明白,或者只是将优先级保持为一个简单的列表,所有前缀运算符组成一个单一的级别?
编辑好的,我没有明确说出来,但是:当然我的意思x是用户定义的类型.对于内置类型,(x+=2)-1当然比更好的(++x)++,并且x+1是一个很多好过(++x)--.我想到的情况是一个相当复杂的半关联容器的迭代器,其中运算符+=和+(为随机访问而设计)必须重建缓存才能有效地处理一般请求,因此是一个命令比...慢++.但是我当然可以将它们修改为总是首先检查参数是否是一个非常小的整数,并且在这种情况下只是operator++反复调用而不是执行随机访问过程.这应该可以正常工作,虽然我可以想象我可能在某种程度上有一种情况,我想operator+=总是采用随机访问方式,无论我呈现的数字有多少.
具有简单的和精心memorizeable优先列表,其中的优点所有之前来后缀运算符任何前缀运营商足以容忍的总是不必使用括号来构成前和后缀运算符的小缺点
++/--,因为该组合物是非常少用.
更简单的"C就是这样做的",虽然看起来可能是真正的原因,但对我来说远不那么令人满意,因为C中++x++根本不允许这样做,所以可以重新定义这个非常复杂的构图而不会损坏任何构图.现有代码.
无论如何,我会继续使用(++x)--,因为括号真的没有那么多伤害.
c++ increment operator-precedence prefix-operator postfix-operator
基本上,我想要做的是手工定义
maybeCombine :: (a->a->a) -> Maybe a -> Maybe a -> Maybe a
maybeCombine _ Nothing Nothing = Nothing
maybeCombine _ (Just a) Nothing = Just a
maybeCombine _ Nothing (Just a) = Just a
maybeCombine f (Just a) (Just a') = Just $ f a a'
Run Code Online (Sandbox Code Playgroud)
在需要的时候在本地定义这个并不是什么大不了的事情,但仍然是笨拙的,并且如此基本和一般似乎应该有一个标准的实现,但我似乎找不到一个.
也许我只是忽略了一些东西.我想要的似乎与monad的行为完全无关,所以我认为我在Monad/Arrow抽屉里找不到任何东西; 但它确实类似于Monoid实例
Prelude Data.Monoid> Just"a"<> Nothing
Just"a"
Prelude Data.Monoid> Just"a"<> Just"b"
Just"ab"
......
...然而a,它本身需要一个幺半群,即它基本上具有a->a->a"内置".该MonadPlus实例的行为也很像我想要的,但它只是抛弃了其中一个值而不是允许我提供组合函数
Prelude Data.Monoid Control.Monad> Just 4`mplus` Nothing
Just 4
Prelude …
虽然沉思什么更有用的标准类建议这一个
class Coordinate c where
createCoordinate :: x -> y -> c x y
getFirst :: c x y -> x
getSecond :: c x y -> y
addCoordinates :: (Num x, Num y) => c x y -> c x y -> c x y
Run Code Online (Sandbox Code Playgroud)
它发生我,而不是其他VectorSpace-y或者R2,一个较为普遍的野兽可能潜伏在这里:一Type -> Type -> Type,其两个包含类型都可以提取.嗯,也许他们可以extract编辑?
事实证明,comonad也没有bifunctors包含一些叫做的东西Bicomonad.问题是,从理论上讲,这类课程是否有意义?不像Bimonad(也没有定义,我真的不知道怎么看),一个天真的定义似乎是合理的:
class Bifunctor c => Bicomonad c where
fst :: …Run Code Online (Sandbox Code Playgroud) 一边琢磨如何最好地映射,即traverse,一个a -> Maybe a-Kleisli在一个未装箱载体,我找了一个现有的实现.显然U.Vector不是Traversable,但它确实提供了一个mapM,Maybe当然工作得很好.
但问题是:Monad真的需要约束吗?好吧,事实证明,甚至盒装向量为Traversable实例作弊:它们实际上只是遍历一个列表,它们从/转换为:
instance Traversable.Traversable Vector where
{-# INLINE traverse #-}
traverse f xs = Data.Vector.fromList Applicative.<$> Traversable.traverse f (toList xs)
Run Code Online (Sandbox Code Playgroud)
mono-traversable 对于未装箱的载体也会做同样的事情 ; 在这里,这似乎更加令人毛骨悚然.
现在,如果vector实际上能够将这些被攻击的遍历融合成更有效的形式,我不会感到惊讶,但仍然 - 似乎存在一个根本问题,阻止我们立即在阵列上实现遍历.这种无能是否存在"深层原因"?
这对任何人来说都很熟悉吗?
[1 of 1] Compiling Main ( Main.hs, Main.o )
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package old-locale-1.0.0.6 ... linking ... done.
Loading package time-1.4.2 ... linking ... done.
Loading package containers-0.5.5.1 ... linking ... done.
Loading package bytestring-0.10.4.0 ... linking ... done.
Loading package text-1.1.0.1 ... linking ... done. …Run Code Online (Sandbox Code Playgroud) 多态"常量",5 :: Num a => a不是真正的常量,而是字典参数的功能.因此,如果你定义
primes :: Num n => [n]
primes = ...
Run Code Online (Sandbox Code Playgroud)
当然不好的例子,这里没有充分的理由让它具有多态性...我真正感兴趣的是如果你尝试全局记忆一个非平凡的多态函数,例如memo-tries.
那么这个序列将不会在来自不同站点的呼叫之间共享,这在性能方面并不好.(这不是Haskell标准用可怕的单态限制祝福我们的主要原因吗?)
我能看到如何强制共享的唯一方法是为约束类的每个实例设置一个单形"标记".例如
erastothenes :: Num n => [n]
erastothenes = ...
class (Num n) => HasPrimes n where
-- | @'primes' ? 'erastothenes'@
primes :: [n]
integerPrimes :: [Integer]
integerPrimes = erastothenes
instance HasPrimes Integer where
primes = integerPrimes
Run Code Online (Sandbox Code Playgroud)
......在优雅方面不是很好.
有没有更好的方法来实现这样的备忘录?
考虑如下的递归数据结构:
data Tree level
= Leaf String
| Node level [ Tree level ]
Run Code Online (Sandbox Code Playgroud)
现在,如果level是一个实例Ord,我想在类型级别强加数据结构的以下限制:一个节点必须只包含Tree更高的s level.
你可以放心地假设这level是一个简单的和类型
Level
= Level1
| Level2
...
| LevelN
Run Code Online (Sandbox Code Playgroud)
但在哪里N不知道先验.在这种情况下,我可以让节点的所有子节点都具有更高的级别.
例如
tree = Node Level1
[ Node Level2 []
, Node Level3 []
]
Run Code Online (Sandbox Code Playgroud)
应该编译,而
tree = Node Level2
[ Node Level1 []
]
Run Code Online (Sandbox Code Playgroud)
不应该.
是否有可能在Haskell中建模这样的东西?
我加入了一个项目。代码库对我来说是新的。我对在代码库中使用的模块感兴趣,它是从依赖项导入的。该模块未在项目中定义。
是否有一种自动/简单的方法来确定哪个库提供了我感兴趣的模块?
许多依赖项是专有的,hoogle 无法帮助我解决这个问题。
我了解到type同义词是现有类型的新名称.它可以像
type MyChar = Char
Run Code Online (Sandbox Code Playgroud)
但这种用法是什么意思呢?
class HasField a where
type FieldType a :: *
Run Code Online (Sandbox Code Playgroud) 签名modifyIORef很简单:
modifyIORef :: IORef a -> (a -> a) -> IO ()
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不是线程安全的.有一个替代方案可以解决这个问题:
atomicModifyIORef :: IORef a -> (a -> (a,b)) -> IO b
Run Code Online (Sandbox Code Playgroud)
这两个功能之间到底有什么区别?b在修改IORef可能从另一个线程读取的参数时,我应该如何使用该参数?
haskell ×9
bifunctor ×1
c++ ×1
cabal ×1
comonad ×1
concurrency ×1
ghc ×1
global-state ×1
increment ×1
ioref ×1
memoization ×1
monads ×1
monoids ×1
performance ×1
unboxing ×1
verbosity ×1