标签: ghc

为什么我不能替换GHC分发的库?如果我做了会怎么样?

我看到这个答案这一个,"一切都可怕突破"和堆栈不会让我代替基地,但它让我代替字节字符串.这有什么问题?有没有办法安全地做到这一点,而无需重新编译GHC?我正在调试基本库的问题,这将非常方便.

NB当我说我想取代base我指的是修改后的版本base同一 GHC版本.我正在调试库,而不是针对不同的GHC版本测试程序.

haskell ghc haskell-stack

2
推荐指数
1
解决办法
100
查看次数

具有相关函数的最小完整定义

我有以下类型类(省略了不相关的方法):

class Initializable a where
    initialize :: IO a
    initialize = return initializePure

    {# convenience method for implementations, not to be called from outside #}
    initializePure :: a

data Foo = Foo

instance Initializable Foo where
    initializePure = Foo

data Bar = Bar

instance Initializable Bar where
    initialize = initializeBar
Run Code Online (Sandbox Code Playgroud)

有些实现需要IO初始化自己,有些则不需要.

此代码发出警告:

No explicit implementation for
  ‘initializePure’
In the instance declaration for ‘Initializable Bar’
Run Code Online (Sandbox Code Playgroud)

我试图添加这样的MINIMALpragma:

{-# MINIMAL initializePure | initialize #-}
Run Code Online (Sandbox Code Playgroud)

但后来我得到了一个不同的警告:

The MINIMAL pragma does …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

2
推荐指数
1
解决办法
103
查看次数

为什么函数的类型在GHCi中出现monad时会发生变化

当一个函数出现在monad中时,它会发生一些变化.

在GHCI中:

> :t map
map :: (a -> b) -> [a] -> [b]
> a <- return map
> :t a
a :: (GHC.Prim.Any -> GHC.Prim.Any)
 -> [GHC.Prim.Any] -> [GHC.Prim.Any]
Run Code Online (Sandbox Code Playgroud)

此更改使得难以将函数存储在更高级别的类型中.

这里发生了什么,我可以让它不会发生吗?

(这也不违反monad法律之一吗?)

polymorphism haskell ghc ghci

2
推荐指数
1
解决办法
109
查看次数

GHC中模式匹配的表现

我正在为我创建的数据类型编写一个"附加"函数(基本上处理"流").但是,这种数据类型有12种不同的构造函数,处理不同类型的"流",例如,无限,空,固定长度,可变长度,已经附加等.

输入类型和输出类型之间的逻辑有点复杂但并非如此令人难以置信.

我考虑过两种方法:

  1. 与广泛的类别匹配(可能通过包装在更简单的代理类型中),然后在这些匹配内匹配OR
  2. 只是模式匹配144个案例(12*12).对于特定的组合,我可以通过通配符匹配将此值减少到100,但这就是它.

我知道第二种方法更难以维护,但忽视这一点,GHC会发现第二种方法更容易优化吗?如果它可以使用简单的跳转表(或者可能是两个跳转表)进行第二种方法,我怀疑它会更快.但是,如果它进行线性检查,它将会慢得多.

GHC是否将模式匹配(甚至非常大的匹配)优化为恒定时间跳转表?

haskell pattern-matching ghc

2
推荐指数
1
解决办法
138
查看次数

Aeson:用Haskell中的未知密钥解析JSON

我想在Haskell中使用Aeson解析以下JSON:

{
    "foo": {
        "name": "name 1",
        "location": "location 1"
    },
    "bar": {
        "name": "name 2",
        "location": "location 2"
    }
}
Run Code Online (Sandbox Code Playgroud)

按键namelocation是已知的,但foobar未知.

我想将JSON数据加载为以下数据类型([Entry])的列表:

data Entry = Entry
        { id :: String       -- "foo" or "bar" etc.
        , name :: String     -- "name 1" or "name 2" etc.
        , location :: String -- "location 1" or "location 2" etc.
        } deriving Show
Run Code Online (Sandbox Code Playgroud)

我的第一次尝试看起来如下(它不起作用):

instance FromJSON Entry where
        parseJSON (Object o) = …
Run Code Online (Sandbox Code Playgroud)

haskell ghc aeson

2
推荐指数
1
解决办法
554
查看次数

返回子类型集

假设我有一个定义为的数据类型

data Foo = Hello Int | World Int
Run Code Online (Sandbox Code Playgroud)

和作为

isWorld :: Foo -> Bool
isWorld (World i) = True
isWorld (Hello i) = False

getWorlds :: Set Foo -> Set World
getWorlds = Set.filter isWorld
Run Code Online (Sandbox Code Playgroud)

这不起作用:

Not in scope: type constructor or class `World'
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为World它只是一个函数,但我不知道如何在Haskell中对此进行建模.使用data正确吗?我希望能够仅为某些实例定义函数:

foo :: World -> Int
foo (World i) = i
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,这会产生同样的错误,因为World它不是一种类型.有没有办法做到这一点,最好没有GHC扩展?

haskell types ghc

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

在Haskell中使用自定义二进制数据类型是一个坏主意吗?

最近我做了一个程序,我使用了以下形式的数据类型:

data MyType = Constructor1 | Constructor2 deriving Eq
Run Code Online (Sandbox Code Playgroud)

是的,这种类型实际上与Bool我刚才命名的不同,以使我的代码更具可读性.在程序的后期,我有表格的功能

myFunc input = if input == Constructor1 then --do something
    else --do something else
Run Code Online (Sandbox Code Playgroud)

我认为这可能是一个坏主意的原因是,如果它被解释为它的方式,每次程序遇到这个分支时,它必须运行==它设置的函数MyType来获得Bool通过对于该if_then_else_功能,如果我刚刚使用Bool==功能的必要性被消除,这将加快该过程.

我应该替换所有实例的MyType实例,Bool还是ghc以某种方式优化数据类型的使用?

haskell ghc

2
推荐指数
1
解决办法
81
查看次数

Haskell中的空间泄漏 - 旧编译器的错误还是我的?显然是后者

我最近参加了竞争性的编码竞赛.

这个Haskell在运行ghc 7.6.3的判断系统上发生了空间泄漏:

t n [] = 0
t n ('8':rest) = t (n+1) rest
t n (')':rest) = n + (t n rest)

main = getLine >>= (\l -> print (t 0 l))
Run Code Online (Sandbox Code Playgroud)

比赛结束后,测试用例发布.其中一个失败案例是:(一个包含10 ^ 5个关闭的parens的文件)​​:https://cses.fi/download/1/b575d19a75bf724b50fa4a399f8187b6d6edb4ccb62bd1a774f9294969152e46

错误是

Stack space overflow: current size 8388608 bytes. Use `+RTS -Ksize -RTS' to increase it.
Run Code Online (Sandbox Code Playgroud)

我也知道代码是用-O2和-Wall编译的,我认为是GHC 7.6.3.

对于我的生活,我无法在我的机器上使用GHC 8.0.2或7.10.3重现错误.

代码中是否有明显的空间泄漏?

编辑:

我测试了下面建议的代码和这样实现的折叠:

import Data.Foldable

t (kasit, score) '8' = (kasit+1, score)
t (kasit, score) _ = (kasit, score+kasit)

main = …
Run Code Online (Sandbox Code Playgroud)

haskell ghc space-leak

2
推荐指数
1
解决办法
112
查看次数

GHC是否减少了编译时不依赖IO的表达式?

如果我有一个类似的程序

main = print ( (+) <$> Just 1 <*> Just 2 )

将编译器决定减少我的程序,它不依赖于的部分IO

( (+) <$> Just 1 <*> Just 2 ) => (Just 3)

或者程序是否仍然创建一个新函数(+) <$> Just 1,然后Just 2在运行时应用它?

haskell ghc

2
推荐指数
1
解决办法
105
查看次数

为什么扩展我的函数依赖会消除非类型变量参数?

我一直在做一些构建我自己的自定义前奏的工作,我想构建一个Callable类型类,它将($)为函数以外的类型实现函数application().所以我使用多参数类型类构建了一个类型类:

{-# Language MultiParamTypeClasses #-}

import Prelude ()

class Callable a b c where
  ($) :: a -> b -> c
Run Code Online (Sandbox Code Playgroud)

现在我继续将函数作为Callable类型类的实例,这需要我启用灵活的实例.

{-# Language MultiParamTypeClasses, FlexibleInstances #-}

import Prelude ()

id :: a -> a
id x = x

class Callable a b c where
  ($) :: a -> b -> c

instance Callable (a -> b) a b where
  ($) = id
Run Code Online (Sandbox Code Playgroud)

这很好,现在我可以($)在函数上使用.因此,对我来说,下一个合乎逻辑的步骤是实现函数组合((.)).经过一段时间的努力,我意识到为了做到这一点,我需要在Callable功能上依赖,所以我打开了功能依赖.

{-# Language MultiParamTypeClasses, FlexibleInstances, …
Run Code Online (Sandbox Code Playgroud)

haskell ghc functional-dependencies

2
推荐指数
1
解决办法
70
查看次数