为什么以下编译:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverlappingInstances #-}
class IsList a where
isList :: a -> Bool
instance IsList a where
isList x = False
instance IsList [a] where
isList x = True
main = print (isList 'a') >> print (isList ['a'])
Run Code Online (Sandbox Code Playgroud)
但改变main来此:
main = print (isList 42) >> print (isList [42])
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
Ambiguous type variable `a0' in the constraints:
(Num a0) arising from the literal `42' at prog.hs:13:22-23
(IsList a0) arising from a use …Run Code Online (Sandbox Code Playgroud) 以课程为例Functor:
class Functor a
instance Functor Maybe
Run Code Online (Sandbox Code Playgroud)
这Maybe是一个类型构造函数.
但我们可以通过其他两种方式实现这一目标:
首先,使用多参数类型:
class MultiFunctor a e
instance MultiFunctor (Maybe a) a
Run Code Online (Sandbox Code Playgroud)
其次使用类型族:
class MonoFunctor a
instance MonoFunctor (Maybe a)
type family Element
type instance Element (Maybe a) a
Run Code Online (Sandbox Code Playgroud)
现在后两种方法有一个明显的优势,即它允许我们做这样的事情:
instance Text Char
Run Code Online (Sandbox Code Playgroud)
要么:
instance Text
type instance Element Text Char
Run Code Online (Sandbox Code Playgroud)
所以我们可以使用单形容器.
第二个优点是我们可以将没有type参数的类型的实例作为最终参数.让我们说我们制作一个Either样式类型但是把类型放错了方法:
data Silly t errorT = Silly t errorT
instance Functor Silly -- oh no we can't do this without a newtype wrapper
Run Code Online (Sandbox Code Playgroud)
而
instance …Run Code Online (Sandbox Code Playgroud) 考虑以下:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
data T = T1 | T2
data D (t :: T) where
D1 :: D T1
D2 :: D T2
D3 :: D d
D4 :: D T1
x1 :: [D T1]
x1 = [D1, D3, D4]
x2 :: [D T2]
x2 = [D2, D3]
Run Code Online (Sandbox Code Playgroud)
基本上x1是所有有效构造函数的列表D T1,并且x2是所有有效构造函数的列表D T2.
但是,我希望这两个列表能够反映添加的任何其他构造函数D,我不想像现在这样对这些列表进行硬编码.
有没有办法定义x1并x2自动生成它们D?
我想我会直接进入它并从代码开始:
#include <iostream>
#include <fstream>
#include <string>
class test : public std::ofstream
{
public:
test(const std::string& filename) { this->open(gen_filename(filename)); };
test(const test&) = delete;
//test(test&& old) = default; // Didn't compile
test(test&& old) {};
private:
std::string gen_filename(const std::string& filename)
{ return filename + ".tmp"; }
};
int main()
{
auto os = test("testfile");
os << "Test1\n";
os << "Test2\n";
}
Run Code Online (Sandbox Code Playgroud)
基本上,我需要返回一个流.当然你不能复制一个ofstream,所以我在类测试中摆弄代码,然后我按照你的预期编译和工作(在gcc 4.5上).
但我感觉不好这只是因为我的编译器在"auto os = test()"上做了"返回值优化"(RTO).的确,如果修改为以下内容:
int main()
{
auto os = test("testfile");
os << "Test1\n";
auto os2 = std::move(os); …Run Code Online (Sandbox Code Playgroud) 阅读关于从函数返回右值引用的这个答案让我思考,如何id在C++ 0x中编写函数.
基本上,我想做id一个什么都不做的功能,这个功能对程序没有任何可观察的影响.
我的第一次尝试如下:
#include <iostream>
class X
{
public:
X(std::string&& s) : s(std::move(s)) {};
X(const std::string& s) : s(s) {};
std::string s;
~X() { std::cout << "Destroying: " << s << std::endl; }
private:
X(const X&) {};
X(X&&) {};
};
template <class T>
T&& id(T&& x) { return static_cast<T&&>(x); }
int main()
{
auto&& x1 = X("x1");
std::cout << "Line 1" << std::endl;
auto&& x2 = id(X("x2"));
std::cout << "Line 2" << std::endl; …Run Code Online (Sandbox Code Playgroud) 我正在考虑使用TVar在Web应用程序中存储某些状态(可以在重新启动时重新创建).然而,TVar的争论方面关注我.似乎频繁的短期交易可以通过不断地中断它们来匮乏更长的交易.此外,随着更长时间运行的事务不断重启,这会增加CPU的负载,趋向于进一步增加这些事务的长度.最终我觉得这可能导致服务器完全没有响应.
考虑到这一点,我有以下问题:
(1)TVar(或其他数据类型)可以使用锁,而不是同时尝试/重试.
(2)可以的TVar(或其它数据类型)有一些不同的竞争机制,即"让交易运行另一个事务前一秒钟跑",或至少一些保证交易将最终完成(即竞争算法,以防止饥饿的更长时间的交易).
我一直试图了解并发性,并且我一直在努力找出更好的,一个大IORef锁或许多TVar.我已经达到了以下指导原则,评论将会受到赞赏,关于这些是否大致正确或是否我错过了这一点.
让我们假设我们的并发数据结构是一个地图m,访问类似m[i].让我们说我们有两个功能,f_easy和f_hard.该f_easy快,f_hard需要很长的时间.我们假设参数f_easy/f_hard是元素m.
(1)如果您的交易看起来大致如此m[f_easy(...)] = f_hard(...),请使用IORefwith atomicModifyIORef.懒惰将确保m仅在短时间内锁定,因为它更新了thunk.计算索引有效地锁定了结构(因为某些内容会更新,但我们还不知道是什么),但是一旦知道该元素是什么,整个结构上的thunk就会移动到thunk上,而不是特定元素,然后只有那个特定元素被"锁定".
(2)如果您的交易看起来大致如此m[f_hard(...)] = f_easy(...),并且不要过多冲突,请使用大量的TVars.IORef在这种情况下使用an 将有效地使应用程序成为单线程,因为您无法同时计算两个索引(因为在整个结构中将存在未解决的thunk).TVars允许你同时计算两个索引,但是,否定的是,如果两个并发事务都访问同一个元素,其中一个是写入,则必须废弃一个事务,这会浪费时间(这可能是用于别处).如果这种情况发生了很多,你可能会更好地使用来自(通过黑洞)的锁定IORef,但如果它不会发生很多,你将获得更好的与TVars的并行性.
基本上在情况(2)中,IORef你可以获得100%的效率(没有浪费的工作),但只使用1.1个线程,但TVar如果你的冲突数量很少,你可能会获得80%的效率,但使用10个线程,所以你仍然结束即使浪费了工作,也要快7倍.
让我们说我有以下代码
type IsTall = Bool
type IsAlive = Bool
is_short_alive_person is_tall is_alive = (not is_tall) && is_alive
Run Code Online (Sandbox Code Playgroud)
说,稍后,我有以下内容
a :: IsAlive
a = False
b :: IsTall
b = True
Run Code Online (Sandbox Code Playgroud)
并调用以下内容,以错误的方式获取两个参数:
is_short_alive_person a b
Run Code Online (Sandbox Code Playgroud)
不幸的是,这成功地编译了,并且在运行时很高的人被发现而不是短暂的活着的人.
我想上面的例子不要编译.
我的第一次尝试是:
newtype IsAlive = IsAlive Bool
newtype IsTall = IsTall Bool
Run Code Online (Sandbox Code Playgroud)
但后来我做不了类似的事情.
switch_height :: IsTall -> IsTall
switch_height h = not h
Run Code Online (Sandbox Code Playgroud)
由于not没有在IsTalls上定义,只有Bools.
我可以一直明确地提取Bools,但这在很大程度上违背了目的.
基本上,我希望IsTalls与其他s进行交互IsTall,就像它们一样Bool,除非他们不会在没有明确演员的情况下与Bools和IsAlives进行交互.
实现这一目标的最佳方法是什么. …
在一些perl脚本中,我发现自己编写的内容如下:
open(...) or die $!;
print ... or die $!;
Run Code Online (Sandbox Code Playgroud)
等等
我想避免重复自己or die ...在每个可能的例外结束时说.
是否有办法强制open()等函数在错误时抛出异常,而不仅仅是错误的返回值?然后,我可以一次性捕获所有可能的异常.
这是一个返回指针对齐的简单函数:
{-# LANGUAGE ScopedTypeVariables #-}
import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable, alignment)
main = return ()
ptrAlign1 :: (Storable a) => Ptr a -> Int
ptrAlign1 _ = alignment (undefined :: a)
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
Could not deduce (Storable a0) arising from a use of `alignment'
from the context (Storable a)
bound by the type signature for
ptrAlign1 :: Storable a => Ptr a -> Int
at prog.hs:8:14-41
The type variable `a0' is ambiguous
Run Code Online (Sandbox Code Playgroud)
如果我ptrAlign像这样重写一个更混乱的派系:
ptrAlign2 :: (Storable a) => …Run Code Online (Sandbox Code Playgroud)