我发现
Prelude> :i ()
data () = () -- Defined in `GHC.Tuple'
instance Bounded () -- Defined in `GHC.Enum'
instance Enum () -- Defined in `GHC.Enum'
instance Eq () -- Defined in `GHC.Classes'
instance Ord () -- Defined in `GHC.Classes'
instance Read () -- Defined in `GHC.Read'
instance Show () -- Defined in `GHC.Show'
Run Code Online (Sandbox Code Playgroud)
所以,mean()是Enum的一个实例,应该已经实现了该succ函数.但是,当我尝试时succ (),我得到了*** Exception: Prelude.Enum.().succ: bad argument
我搜索了GHC.Tuple应该定义()类型的源代码但是GHC.Tuple
当我看到这个非常有趣的例子时,我正在浏览关于TypeNats的GHC维基部分.他们正在创建类型列表:
type family Get (n :: Nat1) (xs :: [*]) :: *
type instance Get Zero (x `: xs) = x
type instance Get (Succ n) (x `: xs) = Get n xs
Run Code Online (Sandbox Code Playgroud)
我想了解更多相关信息.我假设这个功能没有在7.6.1中实现(至少它不能为我编译),并且浏览门票证明是非常压倒性的.知道我应该寻找什么吗?
我正在尝试编写一个接受比较器列表的函数,并返回一个比较器,它将使用第一个比较器比较一对值,如果第一个比较器返回则返回第二个比较器EQ.
我想出的是以下功能:
import Data.Monoid
chainCompare :: [a -> a -> Ordering] -> a -> a -> Ordering
chainCompare = mconcat . map ($)
Run Code Online (Sandbox Code Playgroud)
编辑:chainCompare也可以写成(感谢Vitus指出):
chaincompare = mconcat
Run Code Online (Sandbox Code Playgroud)
使用此功能的示例如下:
import Data.List
import Data.Ord
sortBy (chainCompare [comparing length, comparing sum]) [[1..100], [1..20], [100..200]]
Run Code Online (Sandbox Code Playgroud)
但是,这个函数需要明确地使用比较,所以我试着像这样修改函数:
chainCompare :: Ord b => [a -> b] -> a -> a -> Ordering
chainCompare = mconcat . map (comparing $)
Run Code Online (Sandbox Code Playgroud)
但是,chainCompare在这种情况下会导致编译错误(此外,即使此示例编译,它也不适用于空字符串):
sortBy (chainCompare [length, head]) [['a'..'z'], ['A'..'Z'], "Lorem ipsum dolor sit …Run Code Online (Sandbox Code Playgroud) 假设我们想要编写一个由IO操作支持的通用属性映射,但由于某种原因,我们需要使值类型具有多态性.
type Key = Int
get:: Key -> v -> IO v -- Takes a key and a default value, return the associated value
put:: Key -> v -> IO () -- store (Key,v) pair doing some IO
Run Code Online (Sandbox Code Playgroud)
在这种情况下,自由定理是否需要get并且put只做微不足道的事情,如果是这样,我们可以欺骗ghc的类型系统来实现真正的类型索引IO数据库吗?
我有当前版本的cabal和跑步cabal install Pipe给了我没有问题.但我尝试了这两种进口:
import Control.Proxy
import Control.Pipe
Run Code Online (Sandbox Code Playgroud)
但我收到此错误消息:
Could not find module `Control.Pipe'
It is not a module in the current program, or in any known package.
Run Code Online (Sandbox Code Playgroud)
代理相同.
有任何想法吗?
我最近重新安装了我的Haskell环境,因为我认为在将Mac OS X更新为Mavericks之后,我已将其恢复到恢复之外.
现在每次运行时cabal install cabal-install,都会出现以下错误.
Resolving dependencies...
Configuring cabal-install-1.18.0.3...
/var/folders/4l/qbdvy5xj4q53skv0zn0lhw940000gp/T/8247.c:1:12:
warning: control reaches end of non-void function [-Wreturn-type]
int foo() {}
^
1 warning generated.
Building cabal-install-1.18.0.3...
Preprocessing executable 'cabal' for cabal-install-1.18.0.3...
Main.hs:118:8:
Could not find module `Distribution.Version'
There are files missing in the `Cabal-1.18.1.3' package,
try running 'ghc-pkg check'.
Use -v to see a list of the files searched for.
Failed to install cabal-install-1.18.0.3
cabal: Error: some packages failed to install:
cabal-install-1.18.0.3 failed during the building …Run Code Online (Sandbox Code Playgroud) 我正在努力解决臭名昭着的H-99问题,我正在解决问题#6(找出列表是否是回文).据我所知,大多数解决方案在合理的短名单上都能很好地运作.现在我如何编写一个函数来测试一个很长的列表是否是回文,例如,
let ll = [1..10000000] ++ [10000000, 10000000-1..1] ++ [7]
Run Code Online (Sandbox Code Playgroud)
我(天真或许)试图像这样测试它:
isPalindrome [] = True
isPalindrome [_] = True
isPalindrome [x,y] = x==y
isPalindrome (x:xs) = isPalindrome [x,last xs] && (isPalindrome $ init xs)
Run Code Online (Sandbox Code Playgroud)
我假设,如果isPalindrome [x,last xs]评估False,&&将不会评估昂贵的右侧.
我描述了上面的内容,这是它产生的结果:
Mon Jun 30 18:33 2014 Time and Allocation Profiling Report (Final)
h99 +RTS -p -RTS
total time = 1.29 secs (1292 ticks @ 1000 us, 1 processor)
total alloc = …Run Code Online (Sandbox Code Playgroud) 下面的代码编译得很好:
ecbEncryptRandomly :: RandomGen g => ByteString -> g -> (ByteString, g)
ecbEncryptRandomly bs gen = let key :: AES
(key, newGen) = random gen
in (ecbEncrypt key bs, newGen)
Run Code Online (Sandbox Code Playgroud)
现在,我觉得事情很漂亮,所以我想我只是为我的整个元组提供一个类型注释let:
ecbEncryptRandomly :: RandomGen g => ByteString -> g -> (ByteString, g)
ecbEncryptRandomly bs gen = let (key, newGen) = random gen :: (AES, g)
in (ecbEncrypt key bs, newGen)
Run Code Online (Sandbox Code Playgroud)
GHC不喜欢这一点,并吐出以下错误:
ECBCBCoracle.hs:32:56:
Could not deduce (g ~ g1)
from the context (RandomGen g)
bound by the type signature …Run Code Online (Sandbox Code Playgroud) ByteString的文档提供了以下代码示例:
breakByte :: Word8 -> ByteString -> (ByteString, ByteString)
breakByte 'c' "abcd"
Run Code Online (Sandbox Code Playgroud)
但是,当我写相同时,我得到以下错误(ideone):
Couldn't match expected type `GHC.Word.Word8'
with actual type `Char'
Run Code Online (Sandbox Code Playgroud)
当然'c'是Char,不是Word8.据推测,他们正在使用一些扩展,它允许fromInteger样式函数自动在Char文字上工作,但我不确定是什么.{-# LANGUAGE OverloadedStrings #-}似乎没有任何区别.
此代码仅使用1Mb的RAM:
main = putStrLn $ show $ length (take 2000000 [1..])
Run Code Online (Sandbox Code Playgroud)
虽然此代码使用90Mb的RAM:
nums :: [Int]
nums = nextInts 0
where
nextInts x = x : nextInts (succ x)
main = putStrLn $ show $ length (take 2000000 nums)
Run Code Online (Sandbox Code Playgroud)
如果我这样改变它,它将再次使用1Mb的RAM:
nums :: [Int]
nums = nextInts 0
where
nextInts x
|x == 90000000 = [] -- some large number
|otherwise = x : nextInts (succ x)
main = putStrLn $ show $ length (take 2000000 nums)
Run Code Online (Sandbox Code Playgroud)
问题:有人可以解释为什么第二个代码示例将整个列表存储在RAM中,而第三个代码样本没有这样做.还描述了我应该如何更改第二个样本以使用O(1)RAM并且仍然是无限列表.