我有大量类型的矢量函数
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) 我有一个类型
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指定构造函数?
我有一个类型
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 …
我的代码中有类似于这个类的东西.在我的情况下,将'作为另一个参数添加到类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中的当前记录情况有点棘手.
以新类型为例StateT.两个代码
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
Run Code Online (Sandbox Code Playgroud)
和文档
构造函数
StateT
runStateT :: s -> m (a, s)
说的类型runStateT是s -> 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)在唱片中是好的,但它似乎是错的.
该单态库包含下面的代码片段(应在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) 假设我们将数据类型定义为
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库,总共大约有六个.当我在库中进行一些重构时,我通常需要对每个可执行文件进行一些小的更改.
在我当前的工作流程中,我分别编译每个可执行文件(例如,使用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"模块,这样我就可以同时对它们进行类型检查?
考虑以下示例函数,它们均向纯输入添加随机值:
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,而不是相反。
对我来说,这提供了强有力的证据,我应该写addRand1了addRand2。在此示例中,addRand1具有更真实/更通用的类型,通常在Haskell中捕获重要的抽象。
虽然有“正确的”签名似乎函数式编程的一个重要方面,我也有很多的实际原因addRand2可能是一个更好的签名,即使它可能与写入addRand1的签名。
带接口:
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)我的代码似乎挂在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,但我的程序只是挂起.
haskell ×10
ghc ×3
monads ×2
constructor ×1
newtype ×1
record ×1
synonym ×1
type-kinds ×1
types ×1