我之前曾问过这个问题,经过多次调查后我得出结论,GHC只适用于中缀$
和.
.
对于这个问题,我假设GHC遵循RankNTypes中提到的系统-在仲裁等级中进一步阐述的Haskell Prime页面.
RankNTypes - Haskell Prime页面声明如下:
没有显式签名的参数变量在向上推断中被分配了单型,但是在向下检查中可以继承任意级别类型.
我假设"分配的monotypes"意味着通过将所有限定符移动到最外层,将rank-N类型转换为rank-1类型.
我也相信这是导致我提出上一个问题的异常类型错误的原因.
所以我有几个问题:
1)无论如何让GHC警告(或错误)隐式转换为monotypes?我之前的问题中的类型错误需要一段时间才能解决,转换为monotype的警告比类型错误更有帮助.
2)是否存在隐含的"分配给单一类型"是明智行为的情况,如果是这样,你能举个例子吗?
3)关于缀$
和.
,这些似乎都在GHC的特殊规则.这记录在哪里?GHC有没有其他特殊规则,它们在哪里记录?
我在Haskell和C++(ideone链接)中编写了Project Euler挑战14的代码.他们都记得以前在数组中做过的任何计算.
分别使用ghc -O2
和g++ -O3
运行C++的速度比Haskell版本快10-15倍.
虽然我理解Haskell版本可能运行速度较慢,并且Haskell是一种更好的语言,但我很高兴知道我可以对Haskell版本进行一些代码更改以使其运行得更快(理想情况下在2或2之内) 3个C++版本)?
Haskell代码在这里:
import Data.Array
import Data.Word
import Data.List
collatz_array =
let
upperbound = 1000000
a = array (1, upperbound) [(i :: Word64, f i :: Int) | i <- [1..upperbound]]
f i = i `seq`
let
check_f i = i `seq` if i <= upperbound then a ! i else f i
in
if (i == 1) then 0 else (check_f ((if (even i) …
Run Code Online (Sandbox Code Playgroud) 我知道这是代码有点傻,但有人可以解释为什么这会isList [42]
返回True
而isList2 [42]
打印False
,以及如何防止这种情况?我想更好地理解一些更模糊的GHC类型扩展,我认为这将是一个有趣的例子来弄清楚.
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE IncoherentInstances #-}
class IsList a where
isList :: a -> Bool
instance IsList a where
isList x = False
instance IsList [a] where
isList x = True
isList2 = isList
main =
print (isList 42) >>
print (isList2 42) >>
print (isList [42]) >>
print (isList2 [42])
Run Code Online (Sandbox Code Playgroud) 有人可以解释为什么下面的代码导致GHC 8.0.1永远循环编译,或者这是一个错误?
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
main = return $ f (Just 'c')
data D1 x
data D2
type family TF x = t | t -> x
type instance TF (D1 x, a) = Maybe (TF (x, a))
type instance TF (D2, ()) = Char
f :: TF (x, a) -> ()
f _ = ()
Run Code Online (Sandbox Code Playgroud) 我创建了一个Oracle Text索引,如下所示:
create index my_idx on my_table (text) indextype is ctxsys.context;
Run Code Online (Sandbox Code Playgroud)
然后我可以做以下事情:
select * from my_table where contains(text, '%blah%') > 0;
Run Code Online (Sandbox Code Playgroud)
但是,假设我们在此表中有另一列,比如说group_id
,我想要执行以下查询:
select * from my_table where contains(text, '%blah%') > 0 and group_id = 43;
Run Code Online (Sandbox Code Playgroud)
使用上面的索引,Oracle将不得不搜索包含的所有项目,'blah'
然后检查它们group_id
的所有内容.
理想情况下,我更喜欢只搜索项目group_id = 43
,所以我想要一个像这样的索引:
create index my_idx on my_table (group_id, text) indextype is ctxsys.context;
Run Code Online (Sandbox Code Playgroud)
有点像普通索引,因此可以为每个索引进行单独的文本搜索group_id
.
有没有办法在Oracle中做这样的事情(如果这很重要,我使用的是10g)?
编辑(澄清)
考虑一个包含一百万行的表和以下两列,A
以及B
两个数字.假设有500个不同的值A
和2000个不同的值B
,每行都是唯一的.
现在我们考虑一下 select ... where A = x and B …
考虑以下:
do
x1 <- new 2
set x1 3
x2 <- get x1
y1 <- new 10
set y1 20
y2 <- get y1
return (x2 + y2)
Run Code Online (Sandbox Code Playgroud)
我想要这个结果23
.有没有办法在纯Haskell中实现这样的东西,如果是这样的话怎么样?我理解STRef
这样的事情,但我只是想在普通的Haskell中做到这一点(现在不担心效率).我认为我必须创建一个数据类型并使其成为实例Monad
,但我不确定细节,所以一个有用的例子会有所帮助.
我如何编写一个函数,它接受一个类型的函数元组,ai -> b -> ai
并返回一个函数,该函数接受类型元素的元组,类型的ai
一个元素b
,并将每个元素组合成一个新的元组ai
:
那就是签名应该是这样的
f :: (a1 -> b -> a1, a2 -> b -> a2, ... , an -> b -> an) ->
(a1, a2, ... , an) ->
b ->
(a1, a2, ... , an)
Run Code Online (Sandbox Code Playgroud)
这样:
f (min, max, (+), (*)) (1,2,3,4) 5 = (1, 5, 8, 20)
Run Code Online (Sandbox Code Playgroud)
关键是我可以写:
foldlMult' t = foldl' (f t)
Run Code Online (Sandbox Code Playgroud)
然后做一些像:
foldlMult' (min, max, (+), (*)) (head x, head x, 0, 0) x …
Run Code Online (Sandbox Code Playgroud) 让我们说我有一个内射型家庭 T
type family T a = b | b -> a
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是有一种写作方式:
type family T' = the inverse of T
Run Code Online (Sandbox Code Playgroud)
无需重复所有实例T
但反过来.
这样: T (X1 a (T' a)) = a
看起来这应该工作,因为这两个T
和T'
都射,给出一个方面,它是机械的工作出.
无论如何要写T'
?
可以说我们有以下代码:
#include <iostream>
#include <string>
struct A
{
A() {}
A(const A&) { std::cout << "Copy" << std::endl; }
A(A&&) { std::cout << "Move" << std::endl; }
std::string s;
};
struct B
{
A a;
};
int main()
{
B{A()};
}
Run Code Online (Sandbox Code Playgroud)
在这里,我认为struct A
不是一个聚合,因为它既有非平凡的构造函数,也有std::string
我认为不是聚合的成员.这可能意味着它B
也不是一个聚合体.
然而,我可以聚合初始化B.此外,这可以在没有调用复制或移动构造函数的情况下完成(例如,在ideone上的C++ 0x GCC 4.5.1 ).
这种行为似乎是一种有用的优化,特别是对于没有廉价移动的大型堆栈类型的组合.
我的问题是:这种聚合初始化何时在C++ 0x下有效?
编辑+跟进问题:
下面的DeadMG回答如下:
这根本不是聚合初始化,它是统一初始化,基本上在这种情况下意味着调用构造函数,并且没有复制或移动可能由RVO和NRVO完成.
请注意,当我更改B
为以下内容时:
struct B
{
A a;
B(const A& a_) : a(a_) {}
B(A&& a_) : a(std::move(a_)) {} …
Run Code Online (Sandbox Code Playgroud) 我试图了解Haskell中面向对象的样式编程,知道由于缺乏可变性,事情会有所不同.我玩过类型类,但我对它们的理解仅限于它们作为接口.所以我编写了一个C++示例,它是具有纯基础和虚拟继承的标准菱形.Bat
继承Flying
和Mammal
,以及Flying
和Mammal
继承Animal
.
#include <iostream>
class Animal
{
public:
virtual std::string transport() const = 0;
virtual std::string type() const = 0;
std::string describe() const;
};
std::string Animal::describe() const
{ return "I am a " + this->transport() + " " + this->type(); }
class Flying : virtual public Animal
{
public:
virtual std::string transport() const;
};
std::string Flying::transport() const { return "Flying"; }
class Mammal : virtual public Animal
{
public: …
Run Code Online (Sandbox Code Playgroud) haskell ×8
c++ ×2
ghc ×2
optimization ×2
types ×2
aggregate ×1
c++11 ×1
fold ×1
indexing ×1
monads ×1
oop ×1
oracle ×1
oracle-text ×1
polymorphism ×1
sql ×1
state-monad ×1