小编cro*_*eea的帖子

使用和解除引用(void**)

我想传递一个指向函数的"多态"数组.

我可以在没有警告的情况下做以下事情:

foo (void* ptr);

bar()
{
  int* x;
  ...
  foo(x);
}
Run Code Online (Sandbox Code Playgroud)

gcc显然会自动转换x为a (void*),这只是花花公子.

但是,当我执行以下操作时,我会收到警告:

foo (void** ptr);

bar()
{
  int** x; // an array of pointers to int arrays
  ...
  foo(x);
}

note: expected ‘void **’ but argument is of type ‘int **’
warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么一个传递(int*)(void*)参数不是"不兼容",但(int**)作为一个(void**)论据是什么?

由于所有指针类型都是相同的大小(对吗?因为我使用了C已经有一段时间了),我仍然可以做类似的事情:

void mainFunc1(int** arr, int len)
{
    //goal is to apply …
Run Code Online (Sandbox Code Playgroud)

c pointers void-pointers pointer-to-array

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

生成具有恒定堆栈空间的随机向量

我正在使用Don Stewart 的软件包System.Random.Mersenne.Pure64Control.Monad.Mersenne.Random,它们通常非常快,并且应该有助于避免常见错误,例如使用非严格状态monad.

尽管如此,我设法编写了一些代码,这些代码会导致中等大小的向量堆栈溢出.

import qualified Data.Vector.Unboxed as U
import Data.Int
import System.Random.Mersenne.Pure64
import Control.Monad.Mersenne.Random

main = do
    let dim = 1000000
        y = evalRandom (U.replicateM dim getInt64) (pureMT 13) :: U.Vector Int64
    putStr $ (show $ U.head y)
Run Code Online (Sandbox Code Playgroud)

我猜这一定是由于Vector的replicateM实现中的懒惰,虽然它很难看到,因为它是使用实现的streams.

我如何编写使用常量堆栈空间来采样大向量的代码?

stack-overflow monads haskell lazy-evaluation

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

数据提升语法

我最近发现了Data.Promotion一半的单身人士.它具有大量类型系列,允许在类型级别进行基本上任意计算.我有几个关于用法的问题:

  1. 是什么区别($),(%$),($$),和他们在有关:++$,:.$等等?这些实际上是中缀运营商吗?我的印象是所有中缀类型的构造函数都必须以a开头:.

  2. 我正在尝试在列表上映射构造函数:

    {-# LANGUAGE DataKinds, TypeOperators, PolyKinds #-}
    import Data.Promotion.Prelude
    
    data Foo a b
    type MyList = '[Int, Double, Float]
    
     -- expects one more argument to `Foo`
    type FooList1 b = Map ((Flip Foo) $ b) MyList
    
    -- parse error on the second `b`
    type FooList2 b = Map (($ b) :. Foo) MyList 
    
    Run Code Online (Sandbox Code Playgroud)

    但是我在使用多参数类型构造函数时遇到了麻烦.想法?

  3. 我可以用以下函数替换我用等效函数编写的所有类型函数Data.Promotion:

    type family ListToConstraint …
    Run Code Online (Sandbox Code Playgroud)

haskell ghc type-promotion

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

键入具有不明确类型的应用程序

我最近发现-XTypeApplications,它允许我写缩写我的代码.考虑以下:

{-# LANGUAGE AllowAmbiguousTypes, DataKinds, KindSignatures, RankNTypes, 
             ScopedTypeVariables, TypeApplications #-}

import Data.Tagged
import Data.Proxy

class Foo (a :: Bool) where
  foo :: Tagged a Int

instance Foo 'True where
  foo = 3

instance Foo 'False where
  foo = 4
Run Code Online (Sandbox Code Playgroud)

而不是写作proxy foo (Proxy::Proxy 'True),我现在可以写untag $ foo @'True,这节省了很多Proxy样板.没关系,但我们可以用模糊的类型做得更好:

foo' :: forall (a :: Bool) . (Foo a) => Int
foo' = untag $ foo @a
Run Code Online (Sandbox Code Playgroud)

现在我可以写了foo' @'True!请注意,尽管之前类型不明确-XTypeApplications,但我不再指定类型了a.我认为这很好,但其他人可能不会.所以我希望引入一个包装器 …

haskell ghc

8
推荐指数
0
解决办法
422
查看次数

类型解构

我的数据类型总是至少有两个参数,最后两个参数分别是'q'和'm':

{-# LANGUAGE TypeFamilies, FlexibleContexts, UndecidableInstances, TypeOperators, DataKinds, ConstraintKinds, FlexibleInstances #-}

data D1 q m = D1 q
data D2 t q m = D2 q

class Foo a where -- a has kind * -> *
   f :: a x -> a x

class (Foo b) => Bar b where -- b has kind * -> *
   -- the purpose of g is to change ONE type parameter, while fixing the rest
   -- the intent of the equality constraints …
Run Code Online (Sandbox Code Playgroud)

haskell types type-constructor

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

将GHC与LLVM 3.2一起使用

我安装了LLVM/opt-3.2以及llvm-3.2.0.2,我刚从Ubuntu软件包安装了GHC 7.6.2.但是,当我尝试使用-fllvm -v3编译ghc时,我收到错误:

*** CodeGen:
*** LlVM CodeGen:
Error (figuring out LLVM version): fd:10: hGetLine: end of file

<no location info>:
    Warning: Couldn't figure out LLVM version!
             Make sure you have installed LLVM
*** LLVM Optimiser:
'opt-3.0' '/tmp/ghc17812_0/ghc17812_0.ll' '-o' '/tmp/ghc17812_0/ghc17812_0.bc' '-mem2reg' '--enable-tbaa=true'
*** Deleting temp files:
...
ghc: could not execute: opt-3.0
Run Code Online (Sandbox Code Playgroud)

opt在我的路径,但版本是3.2,而不是3.0.如果不是hackage llvm包让GHC寻找合适的opt版本,它是什么?

llvm ghc

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

runST与unsafePerformIO的实际意义

我想要类似的东西

f :: [forall m. (Mutable v) (PrimState m) r -> m ()] -> v r -> v r -- illegal signature
f gs x = runST $ do
  y <- thaw x
  foldM_ (\_ g -> g y) undefined gs -- you get the idea
  unsafeFreeze y
Run Code Online (Sandbox Code Playgroud)

在Vitus评论的这个问题中,我基本上处于同样的位置:

[I]如果你想在某些结构中保留多态函数,你需要专门的数据类型(例如newtype I = I(forall a.a - > a))或ImpredicativeTypes.

另外,请看这个问题.问题是,这些都是非常难看的解决方案.所以我提出了第三种选择,即通过运行"应该"作为ST计算IO来完全避免多态性.因此f成为:

f :: [(Mutable v) RealWorld r -> IO ()] -> v r …
Run Code Online (Sandbox Code Playgroud)

monads haskell impredicativetypes

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

反转类型族

我有一个"线性"类型的家庭,即形式

type family Foo a
type instance Foo T1 = T2
type instance Foo T2 = T3
...
type instance Foo T9 = T10
Run Code Online (Sandbox Code Playgroud)

在我的特定用例中,定义"反向"族FooRev并然后强制执行约束非常方便(FooRev (Foo x) ~ x):

type family FooRev a
type instance FooRev T10 = T9
type instance FooRev T9 = T8
...
type instance FooRev T2 = T1
Run Code Online (Sandbox Code Playgroud)

反向族允许GHC推断许多类型,否则这些类型由于非注入性而会是模糊的.这与此处提出的想法基本相同.这个解决方案非常有效,但是通过列出所有情况,必须定义"反向"类型系列,这很烦人,编程和容易出错.是否有更通用的方法来定义线性族的反转,例如Foo

haskell type-families

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

实例的约束推断

考虑以下:

{-# LANGUAGE FlexibleContexts #-}
module Foo where

data D a = D a
class Foo b

instance (Num a) => Foo (D a)

f :: (Foo (D a)) => a -> a
f x = x+1
Run Code Online (Sandbox Code Playgroud)

GHC抱怨它无法推断Num a出来f.我希望从Foofor (非重叠)for的实例推断出这个约束D a.

我知道我可以使用GADT D并在Num a那里添加约束,但我希望不必为了D许多不必要的约束而污染构造函数.这种情况有没有希望发生,现在有可能吗?

haskell ghc

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

向实例添加约束时的奇怪行为

我正在使用语法库来处理AST.我有一些奇怪的行为,我不是正在发生的事情.

{-# LANGUAGE TypeOperators, GADTs, FlexibleInstances,
    FlexibleContexts, UndecidableInstances #-}
module Foo where

import Data.Syntactic
import Data.Syntactic.Functional

data Const a where Const :: Const (Full a)
instance Render Const where renderSym Const = "const"

main :: ASTF Const Int
main = foo $ inj Const

class Foo dom where
  foo :: ASTF dom a -> ASTF dom a

instance --(Const :<: dom) => 
    Foo dom where
  foo node | Just Const <- prj node = error "PASS"
  foo _ …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

7
推荐指数
0
解决办法
102
查看次数