小编Cli*_*ton的帖子

Haskell - 模糊类型变量,为什么?

为什么以下编译:

{-# 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)

haskell types

8
推荐指数
1
解决办法
620
查看次数

在类类中使用类型构造函数的任何优点?

以课程为例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)

haskell typeclass

8
推荐指数
2
解决办法
179
查看次数

创建有效构造函数的列表

考虑以下:

{-# 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,我不想像现在这样对这些列表进行硬编码.

有没有办法定义x1x2自动生成它们D

haskell gadt

8
推荐指数
1
解决办法
165
查看次数

如何返回fstream(C++ 0x)

我想我会直接进入它并从代码开始:

#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)

c++ fstream move-semantics return-value-optimization c++11

7
推荐指数
1
解决办法
2822
查看次数

C++ 0x中的"id"函数

阅读关于从函数返回右值引用的这个答案让我思考,如何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)

c++ rvalue-reference c++11

7
推荐指数
1
解决办法
1315
查看次数

哈斯克尔:TVar:预防饥饿

我正在考虑使用TVar在Web应用程序中存储某些状态(可以在重新启动时重新创建).然而,TVar的争论方面关注我.似乎频繁的短期交易可以通过不断地中断它们来匮乏更长的交易.此外,随着更长时间运行的事务不断重启,这会增加CPU的负载,趋向于进一步增加这些事务的长度.最终我觉得这可能导致服务器完全没有响应.

考虑到这一点,我有以下问题:

(1)TVar(或其他数据类型)可以使用锁,而不是同时尝试/重试.

(2)可以的TVar(或其它数据类型)有一些不同的竞争机制,即"让交易运行另一个事务前一秒钟跑",或至少一些保证交易将最终完成(即竞争算法,以防止饥饿的更长时间的交易).

concurrency haskell ghc stm tvar

7
推荐指数
2
解决办法
696
查看次数

Haskell:并发数据结构指南

我一直试图了解并发性,并且我一直在努力找出更好的,一个大IORef锁或许多TVar.我已经达到了以下指导原则,评论将会受到赞赏,关于这些是否大致正确或是否我错过了这一点.


让我们假设我们的并发数据结构是一个地图m,访问类似m[i].让我们说我们有两个功能,f_easyf_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倍.

concurrency performance haskell ioref

7
推荐指数
1
解决办法
842
查看次数

Haskell:使用逻辑上不同的布尔值键入安全性

让我们说我有以下代码

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进行交互.

实现这一目标的最佳方法是什么. …

haskell types casting type-safety

7
推荐指数
3
解决办法
377
查看次数

Perl异常而不是返回值

在一些perl脚本中,我发现自己编写的内容如下:

open(...) or die $!;
print ... or die $!;
Run Code Online (Sandbox Code Playgroud)

等等

我想避免重复自己or die ...在每个可能的例外结束时说.

是否有办法强制open()等函数在错误时抛出异常,而不仅仅是错误的返回值?然后,我可以一次性捕获所有可能的异常.

perl exception-handling exception

7
推荐指数
1
解决办法
145
查看次数

ScopedTypeVariables不会将类型变量带入范围

这是一个返回指针对齐的简单函数:

{-# 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)

haskell ghc type-variables

7
推荐指数
1
解决办法
192
查看次数