TVar如何运作?从我所看到的,它尝试在收到它们后立即运行所有事务,但是,事务完成使其他当前运行的事务无效,然后必须重新启动.这是TVar的工作原理吗?
如果是这种情况,如果每100ms发生1ms长的事务,这是否意味着需要200ms处理的事务永远不会完成?
我正在查看源代码Data.Has并试图弄清楚它是如何工作的.我相信下面的代码是为了让别人"加入"两个值,说a :: A和b :: B成同时具有的功能的新的价值a和b.
我特别不明白type类和实例声明中的含义.
另外我不知道~下面的符号是什么意思.
有人可以从Data.Has.TypeList解释下面的代码吗?
-- | Provides type-list functionality
module Data.Has.TypeList where
import Control.Applicative
import Data.Monoid (Monoid (..))
import Test.QuickCheck (Arbitrary (..), CoArbitrary (..))
import Data.Typeable
import Data.Data
-- | Cons a type onto type-list.
data a ::: b = a ::: b deriving (Show,Eq,Ord,Read,Bounded,Typeable,Data)
-- | The empty type-list.
data TyNil = TyNil deriving (Read,Typeable,Data)
-- | Appends a …Run Code Online (Sandbox Code Playgroud) 我如何在Haskell中编写如下内容:
showSquare :: (Show a, Num a) => a -> String
showSquare x = "The square of " ++ (show x) ++ " is " ++ (show (x * x))
showSquare :: (Show a, not Num a) => a -> String
showSquare x = "I don't know how to square " ++ (show x)
Run Code Online (Sandbox Code Playgroud)
基本上,类似于C++中的boost :: enable_if.
GHC扩展是可以的.
我一直在尝试使用HList来创建记录.
我一直在使用HList-GHCSyntax中定义的运算符.
它到目前为止工作得非常好,允许我写这样的东西:
myRecord =
(param1 .=. "param1value") .*.
(param2 .=. "param2value") .*.
emptyRecord
Run Code Online (Sandbox Code Playgroud)
这允许我执行以下操作:
myRecord .!. param1
Run Code Online (Sandbox Code Playgroud)
以下内容:
myRecord .!. param3
Run Code Online (Sandbox Code Playgroud)
按预期抛出编译错误.如果param3需要,这很好用,因为我得到编译时参数检查.
但我也想处理param3可选的情况.我怎样才能做到这一点?
编辑:以下似乎工作(Empty是一个空类型):
getOptional r l = (hLeftUnion r ((l .=. Empty) .*. emptyRecord)) .!. l
Run Code Online (Sandbox Code Playgroud)
但我真的不知道如何检查Empty调用代码.
考虑以下简单make_pair类:
template <class X, class Y>
struct Pair
{
X x;
Y y;
};
Run Code Online (Sandbox Code Playgroud)
此外,我们将制作一个简单的类来显示任何移动/副本:
struct C
{
C(int n_) : n(n_) {};
C(const C& x) { n = x.n; std::cout << "Copy: " << n << std::endl; }
C(C&& x) { n = x.n; std::cout << "Move: " << n << std::endl; }
int n;
};
Run Code Online (Sandbox Code Playgroud)
然后我们可以运行:
auto z1 = Pair<C, C>{C(1),C(2)};
Run Code Online (Sandbox Code Playgroud)
没有输出,C没有移动或复制.
但是,我们必须在构造函数中指定类型Pair.让我们说我们想推断这些.我们可以这样做:
template <class X, class Y>
Pair<X, Y> make_pair(X&& x, …Run Code Online (Sandbox Code Playgroud) ByteString的hackage文档包含以下示例:
split :: Word8 -> ByteString -> [ByteString]
split '\n' "a\nb\nd\ne" == ["a","b","d","e"]
Run Code Online (Sandbox Code Playgroud)
它好像'\n'被转换为a Word8,但LANGUAGE OverloadedStrings似乎只对字符串有效,而不是字符.我需要包含哪些扩展才能使示例代码生效?
我有一种想法可以($)像通用一样Control.Category概括(.),我已经用这篇文章末尾的代码(也是ideone)完成了.
在这段代码中,我创建了一个名为的类FunctionObject.该类具有($)以下签名的函数:
($) :: f a b -> a -> b
Run Code Online (Sandbox Code Playgroud)
当然,我创建(->)了这个类的实例,因此$继续使用普通函数.
但是这允许你创建特殊的函数,例如,知道它们自己的逆,如下面的例子所示.
我总结说有三种可能性之一:
选项1似乎不太可能,我对hayoo的搜索没有显示选项2,所以我怀疑选项3是最有可能的,但如果有人可以解释为什么那就是好的.
import Prelude hiding ((.), ($))
import Control.Category ((.), Category)
class FunctionObject f where
($) :: f a b -> a -> b
infixr 0 $
instance FunctionObject (->) where
f $ x = f x
data InvertibleFunction a b =
InvertibleFunction (a -> b) …Run Code Online (Sandbox Code Playgroud) 可以说我有以下内容
import Control.Category (Category, (.), id)
data Invertible a b = Invertible (a -> b) (b -> a)
instance Category Invertible where
id = Invertible Prelude.id Prelude.id
(Invertible f f') . (Invertible g g') =
Invertible (f Prelude.. g) (g' Prelude.. f')
invert (Invertible x y) = Invertible y x
Run Code Online (Sandbox Code Playgroud)
请注意,以下情况属实:
invert (g . f) == invert f . invert g
Run Code Online (Sandbox Code Playgroud)
这个结构看起来非常类似于逆变函子(维基百科),因为它遵循相同的公理:
F(g . f) = F(f) . F(g)
Run Code Online (Sandbox Code Playgroud)
就我而言,F简直就是这样invert.
我查看了Data.Functor.Contravariant.contramap,它具有以下类型的函数:
(a …Run Code Online (Sandbox Code Playgroud) 让我说我上课了:
class C a b t where
f :: (a, b) -> (t a, t b)
Run Code Online (Sandbox Code Playgroud)
现在有了这个定义,我可以定义实例:
(a,b) -> (Maybe a, Maybe b)
(a,b) -> ([a], [b])
Run Code Online (Sandbox Code Playgroud)
但不是(据我所知):
(a,b) -> (a,b)
(a,b) -> ((a, a), (b, b))
Run Code Online (Sandbox Code Playgroud)
我可以改为改变我的类定义:
type family T a b x
class C a b where
f :: (a, b) -> (T a b a, T a b b)
Run Code Online (Sandbox Code Playgroud)
这将允许我做上面的事情,但后来我只能f为每个声明一个a和b.
基本上我希望能够像t原始定义一样传递类型系列,如果已知,则由类型检查器隐式解析.我不想只是f :: (a, b) -> (c, d)因为我想保持两者的不变量 …
我正在开发一个代表键/值映射的类,我有一个基本上是这样的函数alterF:
class C t where
...
alterF :: Functor f =>
(Maybe (Value t) -> f (Maybe (Value t))) -> Key t -> t -> f t
Run Code Online (Sandbox Code Playgroud)
不幸的是,这打破了GeneralisedNewtypeDeriving.在某些情况下,这是合理的,因为GeneralisedNewtypeDeriving从我理解的本质上使用Coercible和函数coerce.Coercible表示在表示上相等的类型,即它们在运行时具有相同的表示,因此我们可以在它们之间进行免费转换.例如,给定:
newtype T a = T a
Run Code Online (Sandbox Code Playgroud)
我们有:
Coercible a (T a)
Coercible (T a) a
Run Code Online (Sandbox Code Playgroud)
但我们没有(一般情况下):
Coercible (f a) (f (T a))
Coercible (f (T a)) (f a)
Run Code Online (Sandbox Code Playgroud)
例如,GADT违反了这种代表性的平等.但是有很多值f的确有效.例如:
Coercible (Maybe a) (Maybe (T a))
Coercible (Maybe (T …Run Code Online (Sandbox Code Playgroud) haskell ×9
bytestring ×1
c++ ×1
c++11 ×1
concurrency ×1
constructor ×1
enable-if ×1
hlist ×1
templates ×1
tvar ×1
typeclass ×1