小编cro*_*eea的帖子

确定临时类型变量的范围

我有大量类型的矢量函数

f :: (M.MVector v r, PrimMonad m) => 
     v (PrimState m) r -> v (PrimState m) r -> m ()
Run Code Online (Sandbox Code Playgroud)

这些函数大部分都是就地工作,所以将它们的参数作为一个可变向量很方便,这样我就可以编写,迭代等等.但是,在顶层,我只想使用不可变的"Haskell"/纯向量.

以下是问题的示例:

{-# LANGUAGE TypeFamilies, 
             ScopedTypeVariables, 
             MultiParamTypeClasses, 
             FlexibleInstances #-}

import Data.Vector.Generic as V hiding (eq)
import Data.Vector.Generic.Mutable as M
import Control.Monad.ST
import Control.Monad.Primitive

f :: (M.MVector v r, PrimMonad m) => 
     v (PrimState m) r -> v (PrimState m) r -> m ()
f vIn vOut = do val <- M.read vIn 0
                M.write vOut 0 val …
Run Code Online (Sandbox Code Playgroud)

monads haskell

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

定义newtype的构造函数

我有一个类型

class IntegerAsType a where
  value :: a -> Integer

data T5
instance IntegerAsType T5 where value _ = 5

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
Run Code Online (Sandbox Code Playgroud)

我四处寻找指定newtype的构造函数的方法.我意识到只能有一个,但我不明白为什么我可以指定它是什么.

例如,我可能只想将参数的前三个元素带到PolyRing值构造函数中.

我尝试where在newtype声明的末尾添加一个子句,但是没有编译.

我也尝试过:

(PolyRing xs) = PolyRing [2, 3, 5, 7]
Run Code Online (Sandbox Code Playgroud)

作为一个玩具的例子.我认为应该做的是忽略值构造函数的参数并始终具有值[2,3,5,7].代码编译,但我的"自定义"构造函数没有效果.

是否可以为newtype指定构造函数?

constructor haskell newtype

4
推荐指数
1
解决办法
503
查看次数

Haskell 获取代数参数的类型

我有一个类型

class IntegerAsType a where
  value :: a -> Integer

data T5
instance IntegerAsType T5 where value _ = 5

newtype (IntegerAsType q) => Zq q = Zq Integer deriving (Eq)

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
Run Code Online (Sandbox Code Playgroud)

我正在尝试为 PolyRing 类型制作一个不错的“表演”。特别是,我希望“show”打印出类型“a”。是否有返回代数参数类型的函数(类型的“显示”)?

我尝试使用的另一种方法是使用模式匹配,但我遇到了内置类型和代数类型的问题。

我想要 Integer、Int 和 Zq q 中的每一个都有不同的结果。(玩具示例:)

test :: (Num a, IntegerAsType q) => a -> a
(Int x) = x+1
(Integer x) = x+2
(Zq x) = x+3
Run Code Online (Sandbox Code Playgroud)

这里至少有两个不同的问题。

1) Int …

haskell pattern-matching

4
推荐指数
1
解决办法
1487
查看次数

类型同义词中的模式匹配/内部类型参数的类型同义词

我的代码中有类似于这个类的东西.在我的情况下,将'作为另一个参数添加到类Foo是没有意义的.

class Foo a where
    type FCtx a a' :: Constraint
    type FCtx a a' = ()

    f :: (FCtx a a') => a -> a'

data D b = D b

instance (Integral b) => Foo (D b) where
    -- the next line does not compile because b' does not appear on the LHS
    type FCtx (D b) a' = (a' ~ D b', Integral b') 

    f (D x) = D $ fromIntegral x
Run Code Online (Sandbox Code Playgroud)

对于这个特定的例子Foo,我希望 …

haskell types pattern-matching synonym type-parameter

4
推荐指数
1
解决办法
271
查看次数

记录字段的类型不一致

在阅读了一下之后,似乎Haskell中的当前记录情况有点棘手.

以新类型为例StateT.两个代码

newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
Run Code Online (Sandbox Code Playgroud)

文档

构造函数

StateT

runStateT :: s -> m (a, s)

说的类型runStateTs -> m (a,s).但是,GHCi表明这种类型确实存在

> :t runStateT
runStateT :: StateT s m a -> s -> m (a,s)
Run Code Online (Sandbox Code Playgroud)

这种差异有什么解释吗?记录和函数中的标识符是指两个不同的东西,GHC在幕后神奇地解决了吗?虽然我知道为什么写s -> m (a,s)在唱片中是好的,但它似乎是错的.

haskell record

4
推荐指数
1
解决办法
94
查看次数

多态"翻转"在7.10中失败

单态库包含下面的代码片段(应在7.8希望编译):

{-# LANGUAGE DataKinds, ExistentialQuantification, FlexibleContexts, GADTs #-}
{-# LANGUAGE ImpredicativeTypes, PolyKinds, RankNTypes, TypeFamilies       #-}
{-# LANGUAGE TypeOperators, UndecidableInstances                           #-}

class Monomorphicable k where
  type MonomorphicRep k :: *

withPolymorphic :: Monomorphicable k
               => MonomorphicRep k -> (forall a. k a -> b) -> b
withPolymorphic k trans = undefined

-- | Flipped version of 'withPolymorphic'.
liftPoly :: Monomorphicable k
         => (forall a. k a -> b) -> MonomorphicRep k -> b
liftPoly = flip withPolymorphic
Run Code Online (Sandbox Code Playgroud)

然而在7.10,GHC抱怨:

Couldn't …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

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

对类型类型使用'fmap-like'函数*

假设我们将数据类型定义为

data A a = A' a deriving Show 
Run Code Online (Sandbox Code Playgroud)

我们有

A :: * -> *
Run Code Online (Sandbox Code Playgroud)

然后,我们可以将A作为以下实例Functor:

instance Functor A where fmap f (A' x) = A' (f x)
Run Code Online (Sandbox Code Playgroud)

这允许我们创建类型的值A并使用fmap将函数应用于包装的值

Prelude> let x = A' 1
Prelude> fmap (+1) x
A' 2
Run Code Online (Sandbox Code Playgroud)

现在,如果我们定义A

data A = A' Int deriving Show
Run Code Online (Sandbox Code Playgroud)

那种A

A :: *
Run Code Online (Sandbox Code Playgroud)

因此,我们无法创建AFunctor的实例 -

instance Functor A where fmap f (A' x) = A' (f x)

<interactive>:4:18: …
Run Code Online (Sandbox Code Playgroud)

haskell type-kinds

4
推荐指数
1
解决办法
84
查看次数

Typechecking multiple'Main'

我有一个带有几个可执行文件(测试,基准测试等)的Haskell库,总共大约有六个.当我在库中进行一些重构时,我通常需要对每个可执行文件进行一些小的更改.

在我当前的工作流程中,我分别编译每个可执行文件(例如,使用GHCi)并修复每个可执行文件.这很乏味,因为我必须输入每个可执行文件的路径,而且必须重新加载所有(非常大)的库,即使使用GHCi也需要一些时间.

我首先想到解决这个问题的方法是创建一个导入可执行"Main"模块的虚拟模块.但是,这(当然)要求"Main"模块具有类似的模块名称module Executable1 where ....但是现在cabal抱怨在编译可执行文件时它无法找到一个名为"Main"的模块(尽管在每个可执行文件的cabal文件中明确列出了"main-is".)

我也试过了ghci Exec1.hs Exec2.hs ...,但它抱怨道module ‘main@main:Main’ is defined in multiple files.

有没有一种简单的方法可以同时使用GHCi加载多个"Main"模块,这样我就可以同时对它们进行类型检查?

haskell ghc

4
推荐指数
1
解决办法
494
查看次数

有关编写单子签名的建议

考虑以下示例函数,它们均向纯输入添加随机值:

addRand1 :: (MonadRandom m) => m (Int -> Int)

addRand2 :: (MonadRandom m) => Int -> m Int -- *can* be written as m (Int -> Int)
Run Code Online (Sandbox Code Playgroud)

这是很容易转换addRand1成一个函数相同的签名addRand2而不是相反

对我来说,这提供了强有力的证据,我应该写addRand1addRand2。在此示例中,addRand1具有更真实/更通用的类型,通常在Haskell中捕获重要的抽象。

虽然有“正确的”签名似乎函数式编程的一个重要方面,我也有很多的实际原因addRand2可能是一个更好的签名,即使它可能与写入addRand1的签名。

  1. 带接口:

    class FakeMonadRandom m where
      getRandom :: (Random a, Num a) => m a
      getRandomR1 :: (Random a, Num a) => (a,a) -> m a
      getRandomR2 :: (Random a, Num a) …
    Run Code Online (Sandbox Code Playgroud)

monads haskell

4
推荐指数
1
解决办法
123
查看次数

readMVar不会在putMVar上唤醒

我的代码似乎挂在readMVar另一个线程调用之后putMVar.我不指望这会发生,但这就是我所观察到的.我的主线程创建了两个新线程,每个线程都可以访问共享MVarm.

线程1:

do
  putStrLn "tick"
  x <- readMVar m
  putStrLn "tock"
Run Code Online (Sandbox Code Playgroud)

线程2:

do
  putMVar m 0
  putStrLn "put m0"
  void $ tryTakeMVar m
  putStrLn "take m"
  putMVar m 1
  putStrLn "put m1"
Run Code Online (Sandbox Code Playgroud)

主要:

do
  m <- newEmptyMVar
  <start thread 1>
  <start thread 2>
Run Code Online (Sandbox Code Playgroud)

在以下场景中,我的程序挂起:

两个线程可以访问共享的MVar m,它最初是空的.线程1阻塞readMVar m.同时,线程2调用putMVar m ....此时,线程1 可以继续,但我们假设它没有.线程2然后调用tryTakeMVar m,这可能会清空一个完整的MVar.然后线程2再次调用putMVar m ....此方案对应于以下输出:

tick
put m0
take m
put m1
<hang>
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?我希望"tock"应该打印,因为线程2填满了MVar,但我的程序只是挂起.

multithreading haskell ghc

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