小编And*_*tin的帖子

GHC StablePointer平等推理

我刚刚了解了GHC的StablePointer功能,这很酷,但我无法弄清楚为什么它不会显示相同的东西.这是我的测试用例:

-- Example 1
import System.Mem.StableName

data Wrapper = Wrapper { getWrapper :: Int -> Bool }

myFunc :: Int -> Bool
myFunc = (> 4)

main :: IO ()
main = do
  let m = Wrapper myFunc
  a <- makeStableName $ getWrapper m
  b <- makeStableName $ getWrapper m
  print (a `eqStableName` b)
  putStrLn "Done"
Run Code Online (Sandbox Code Playgroud)

非常简单,但是当我runhaskell使用GHC 7.8.4时,我得到了错误的结果.一个更简单的案例怎么样?我们试试这个:

-- Example 2
import System.Mem.StableName

main :: IO ()
main = do
  let m = (+2) :: Int …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

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

通过蕴涵削弱乙烯基的RecAll约束

乙烯基库中,有一个RecAll类型族,让我们要求对类型级别列表中的每个类型使用部分应用的约束.例如,我们可以这样写:

myShowFunc :: RecAll f rs Show => Rec f rs -> String
Run Code Online (Sandbox Code Playgroud)

这一切都很可爱.现在,如果我们的约束RecAll f rs c在哪里c是未知的,并且我们知道c x需要d x(借用ekmett的contstraints包中的语言),我们怎么能得到RecAll f rs d

我问的原因是我正在处理一些需要满足几个类型类约束的函数中的记录.要,我现在用的是做这个:&:组合子从Control.Constraints.Combine模块中存在的包.(注意:如果安装了其他东西,则不会构建软件包,因为它依赖于超级旧版本contravariant.您可以复制我提到的一个模块.)有了这个,我可以得到一些非常漂亮的约束,同时最小化类型类肉鸡.例如:

RecAll f rs (TypeableKey :&: FromJSON :&: TypeableVal) => Rec f rs -> Value
Run Code Online (Sandbox Code Playgroud)

但是,在这个函数的主体内部,我调用另一个需要较弱约束的函数.它可能看起来像这样:

RecAll f rs (TypeableKey :&: TypeableVal) => Rec f rs -> Value
Run Code Online (Sandbox Code Playgroud)

GHC无法看到第二个声明来自第一个声明.我认为情况就是这样.我看不到的是如何证明它以实现它并帮助GHC.到目前为止,我有这个:

import Data.Constraint

weakenAnd1 :: ((a …
Run Code Online (Sandbox Code Playgroud)

haskell constraints ghc vinyl

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

总和类型函数参数的GHC调用约定

GHC在将它们传递给函数时是否会解压缩类型?例如,假设我们有以下类型:

data Foo
  = Foo1 {-# UNPACK #-} !Int {-# UNPACK #-} !Word
  | Foo2 {-# UNPACK #-} !Int
  | Foo3 {-# UNPACK #-} !Word
Run Code Online (Sandbox Code Playgroud)

然后我在其Foo参数中定义一个严格的函数:

consumeFoo :: Foo -> Int
consumeFoo x = case x of ...
Run Code Online (Sandbox Code Playgroud)

在运行时,当我打电话时,我consumeFoo可以期待发生什么?该GHC调用约定是通过参数寄存器(或在栈上一次有太多).我可以看到论证传递的两种方式:

  1. 指向Foo堆上的指针作为一个参数传入.
  2. 使用三参数表示Foo,一个参数表示使用的数据构造函数,另外两个表示数据构造函数中的可能IntWord值.

我更喜欢第二种表示,但我不知道它是否真的发生了什么.我知道UnpackedSumTypes登陆GHC 8.2,但目前还不清楚它是否符合我的要求.如果我把函数写成:

consumeFooAlt :: (# (# Int#, Word# #) | Int# | Word# #) -> Int
Run Code Online (Sandbox Code Playgroud)

那么我希望评估(2)会发生什么.而且开箱部分解压后的款项页面的指示,我能做到这一点,以及:

data Wrap = Wrap …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

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

为什么haskell的网络库使用非阻塞套接字?

我正在努力更好地理解网络库中的设计决策.信誉良好的来源在github问题和使用非阻塞套接字的邮件列表响应中提及network.他们使用select来阻止,直到套接字准备好被读取,而不是使用默认的阻塞行为.为什么这样更好?无论哪种方式,它最终都会阻塞,并且network只向最终用户公开阻止API.我的猜测是,阻止FFI调用是不好的,并且存在某种GHC魔法select,但我无法证实这一点.

作为未成年人之外,我找不到地方select在叫network.打顶代码库没有出现任何问题.我刚刚发现了GHC.Event,它似乎提供了可以用来代替select直接调用的函数,但是grepping shownetwork也没有使用它.

haskell ghc

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

将类型级别列表转换为值

该模块GHC.TypeLits目前提供natValsymbolVal,这使我们能够获得从类型的一种运行时值NatSymbol.有没有办法让类型的运行时值[String]出型样的'[Symbol]?我看不出一个明显的方法来做到这一点.我可以想到一个使用类型类的东西OverlappingInstances,但似乎GHC应该已经有了这个功能.

haskell ghc type-level-computation

6
推荐指数
1
解决办法
530
查看次数

Data.Vector.Mixed的目的

在Edward Kmett的混合向量库中,有两个主要模块:Data.Vector.HybridData.Vector.Mixed.有一篇关于前者背后动机的文章.后者是顺便提到但没有任何解释.我正在试图找出它的用例.到目前为止我注意到了两件事:

  1. 有一个Mixed带有Typeable约束的类型类.我不明白黑线鳕的解释,但似乎Typeable必须要求恢复类型信息或在某些时候安全施放.
  2. Vector数据类型是仅在所述底层参数MVector.这与Hybrid通过两个矢量类型和一个元组进行参数化的模块不同.

我将不胜感激任何有用的见解或(甚至更好)用例的小例子.谢谢.

haskell vector ghc

6
推荐指数
1
解决办法
592
查看次数

为什么GHC Sparks会失败?

我有一个简单的例程,它采用了向量的乘积Double.我试图并行化这个代码,但许多火花最终失败了.这是一个独立的基准,也作为要点提供:

{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}

{-# OPTIONS_GHC -O2 -Wall -threaded -fforce-recomp #-}

import Criterion.Main
import Control.Monad (when)
import Control.Parallel.Strategies (runEval,rpar,rseq)
import qualified Data.Vector.Primitive as PV

main :: IO ()
main = do
  let expected = PV.product numbers
  when (not (serialProduct numbers == expected)) $ do
    fail "serialProduct implementation incorrect"
  defaultMain
    [ bgroup "product"
      [ bench "serial" $ whnf serialProduct numbers
      , bench "parallel" $ whnf parallelProduct numbers
      ]
    ]

numbers :: PV.Vector …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

6
推荐指数
1
解决办法
1109
查看次数

了解Yesod Persistent TH生成的代码

我花了一些时间试图理解模板haskell生成的代码,在这个例子中取自Yesod书:

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
    name String
    age Int
    deriving Show
Car
    color String
    make String
    model String
    deriving Show
|]
Run Code Online (Sandbox Code Playgroud)

我觉得我经常看到发生了什么(很多类型编组),但有一节仍然让我感到困惑:

instance PersistEntity (PersonGeneric backend) where
  data instance Unique (PersonGeneric backend) =
  data instance EntityField (PersonGeneric backend) typ
      = typ ~ KeyBackend backend (PersonGeneric backend) => PersonId |
        typ ~ String => PersonName |
        typ ~ Int => PersonAge
  type instance PersistEntityBackend (PersonGeneric backend) =
      backend
Run Code Online (Sandbox Code Playgroud)

数据实例instance EntityField (PersonGeneric backend) typ有三个数据构造函数,这是有意义的(数据库中的每一列都有一个),但即使在查找了代号在haskell中的作用之后,我也无法理解它在那里做了什么.=>通常用于通用量化的原因通常用于似乎没有任何类型的东西?

如果我能以某种方式更清楚,请告诉我.

haskell persistent yesod

5
推荐指数
1
解决办法
214
查看次数

getCurrentTime如何在GHCJS下工作?

在GHCJS下,如何getCurrentTime运作?在time库本身中,这是使用FFI实现的,调用操作系统提供的功能.但是,time开头没有任何行:

foreign import javascript ...
Run Code Online (Sandbox Code Playgroud)

我检查了shimsGHCJS用来修补库的存储库.它修补了时区获取功能,但没有提及getCurrentTime.我发现的唯一远程关闭的东西是在ghcjs-boot哪里old-time修补:

#ifdef ghcjs_HOST_OS
type CTimeVal = ()
type CTimeZone = ()
...
foreign import ccall unsafe "HsTime.h __hscore_gettimeofday"
    gettimeofday :: Ptr CTimeVal -> Ptr CTimeZone -> IO CInt
...
Run Code Online (Sandbox Code Playgroud)

但是这有两个问题.一个是它不是正确的库(old-time而不是time).另一个是它仍在使用C FFI.我不明白在使用GHCJS进行编译时如何使用C FFI.

那么,哪里getCurrentTime可以为GHCJS填充?

在回复关于grepping ghcjs源的评论时,如果我getTime在GHCJS的源代码中搜索(我相信这将是使用的javascript函数),我基本上什么也得不到.但是,通过all.jsgreping GHCJS为使用的项目生成的文件getCurrentTime,我得到:

ag '\bgetTime\b' all.js
20948:  h$log((("elapsed time: " + (h$RTS_597.getTime() …
Run Code Online (Sandbox Code Playgroud)

haskell ghcjs

5
推荐指数
0
解决办法
140
查看次数

C 编译器针对危险强制转换的警告

对于我所知道的所有 C 编译器,-Wall都会对隐式转换发出警告,但不会对任何显式转换发出警告。我一直在尝试找到一个标志(无论是 gcc、clang、任何 c 编译器都可以),当存在导致未定义或实现定义的行为的强制转换时,该标志将导致发出警告。这是一个示例,说明了我期望和不期望出现警告的位置:

#include <math.h>

struct person {
  int tag;
  char* name;
};

int foo(struct person* p) {
  int* tagPtr = (int*)p; // this cast is fine, cast to first member ptr is allowed
  double* badPtr = (double*)p; // this cast should cause warning
  return ((*tagPtr) + (int)(round(*badPtr)));
}
Run Code Online (Sandbox Code Playgroud)

到 a 的转换int*是明确定义的,并且到double*没有明确定义,但 gcc 不会警告我有关第二次强制转换的信息。有没有办法让它这样做?或者其他编译器甚至 linter 是否提供此功能?

然后是“明确定义的”和“明确定义的实现”之间的区域,即“可以根据上下文进行明确的定义”。例如,如果 a最初是通过另一个方向的转换形成的(由 C 规范的 6.7.2.1p15 节暗示),则从aint*到 a 的转换struct person*是明确定义的。int*指针的出处很少可用,因此编译器或 …

c gcc clang compiler-warnings gcc-warning

5
推荐指数
1
解决办法
499
查看次数