在"任意等级类型的实用类推理"中,作者讨论了包含:
我尝试在GHCi中测试的东西,但是即使g k2
是为了进行类型检查,当我尝试使用GHC 7.8.3时也不会:
?> :set -XRankNTypes
?> let g :: ((forall b. [b] -> [b]) -> Int) -> Int; g = undefined
?> let k1 :: (forall a. a -> a) -> Int; k1 = undefined
?> let k2 :: ([Int] -> [Int]) -> Int; k2 = undefined
?> :t g k1
<interactive>:1:3: Warning:
Couldn't match type ‘a’ with ‘[a]’
‘a’ is a rigid type variable bound by
the type forall a1. a1 …
Run Code Online (Sandbox Code Playgroud) 当由一个Linux/i386的系统上GCC生成的ELF可执行文件看,似乎它调用"主"和"NOP"的填充,如在此之前之后alwas放置一个暂停指令(0xF4中):
? ....... ! entrypoint:
? ....... ! xor ebp, ebp
? 80482e2 ! pop esi
? 80482e3 ! mov ecx, esp*emphasized text*
? 80482e5 ! and esp, 0fffffff0h
? 80482e8 ! push eax
? 80482e9 ! push esp
? 80482ea ! push edx
? 80482eb ! push __libc_csu_fini
? 80482f0 ! push __libc_csu_init
? 80482f5 ! push ecx
? 80482f6 ! push esi
? 80482f7 ! push main
? 80482fc ! call wrapper_804a004_80482c4
? 8048301 ! hlt <--- halt …
Run Code Online (Sandbox Code Playgroud) 我想在Haskell中使用Vector
s 编写Floyd-Warshall所有对最短路径算法的有效实现,以期获得良好的性能.
实现非常简单,但不使用三维| V |×| V |×| V | 矩阵,使用二维向量,因为我们只读过前一个k
值.
因此,该算法实际上只是传递2D矢量的一系列步骤,并且生成新的2D矢量.最终的2D矢量包含所有节点(i,j)之间的最短路径.
我的直觉告诉我,确保在每个步骤之前评估先前的2D向量是很重要的,所以我使用了函数BangPatterns
的prev
参数fw
和严格foldl'
:
{-# Language BangPatterns #-}
import Control.DeepSeq
import Control.Monad (forM_)
import Data.List (foldl')
import qualified Data.Map.Strict as M
import Data.Vector (Vector, (!), (//))
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as V hiding (length, replicate, take)
type Graph = Vector (M.Map Int Double)
type TwoDVector = Vector (Vector Double)
infinity :: Double
infinity = 1/0
-- …
Run Code Online (Sandbox Code Playgroud) 我试图RankNTypes
在Haskell中理解并找到了这个例子:
check :: Eq b => (forall a. [a] -> b) -> [c] -> [d] -> Bool
check f l1 l2 = f l1 == f l2
Run Code Online (Sandbox Code Playgroud)
(如果我的理解是正确的,这相当于check :: forall b c d. Eq b => (forall a. [a] -> b) -> [c] -> [d] -> Bool
.)
好的,到目前为止一切顺利.现在,如果forall a
删除了explicit ,GHC会产生以下错误:
Could not deduce (c ~ a)
from the context (Eq b)
[…]
Could not deduce (d ~ a)
from the context (Eq b)
[…] …
Run Code Online (Sandbox Code Playgroud) 以下函数f
尝试Int
使用IO (Maybe Int)
函数两次读取两次,但在成功读取一次后执行"短路"执行Int
:
readInt :: IO (Maybe Int)
f :: IO (Maybe Int)
f = do
n1 <- readInt
case n1 of
Just n' -> return (Just n')
Nothing -> do
n2 <- readInt
case n2 of
Just n' -> return (Just n')
Nothing -> return Nothing
Run Code Online (Sandbox Code Playgroud)
有没有一种很好的方法来重构这段代码?如果我将它扩展到三次尝试,这将变得非常毛茸茸......
(我的思维过程:看到这个"staircasing"告诉我,也许我应该使用Monad
的情况Maybe
,但由于这是已经在IO
单子,我将不得不使用MaybeT
(),但我只需要?一个的readInt
来成功,所以Maybe
monad在第一次Nothing
出错的行为在这里是错误的...)
仆人服务器处理程序是 , 的新类型包装器ExceptT
,并且具有MonadThrow
, MonadCatch
,MonadError
等的实例。
这可能是一个有点人为的例子,但它显示了我经常面临的一个问题:
\n\n在处理程序中,我想调用三个返回的函数Either String Int
,然后执行类型的计算,获取之前的Int -> Int -> Int -> IO (Either SomeError Text)
三个s 。Int
我应该如何构造这段代码以确保尽早返回错误?
\n\n我看到我可以使用Either
\'sMonad
实例将 \xe2\x80\x9ccollapse\xe2\x80\x9d 的前三个Either String Int
计算放入 eg 中Either String (Int,Int,Int)
,然后将IO
计算绑定到某个结果值,然后用于case
决定是否返回成功结果或用于throwError
抛出SomeError
类型(转换后?),但我希望能够执行以下操作:
f, g, h :: Either String Int\na :: Int -> Int -> Int -> IO (Either SomeError …
Run Code Online (Sandbox Code Playgroud) (这是来自Typeclassopedia的练习.)
如何计算两个非平凡函数的组合类型,如foldMap . foldMap
?
对于简单的情况,这很简单:只需看看它的类型 (.)
(.) :: (b -> c) -> (a -> b) -> (a -> c)
Run Code Online (Sandbox Code Playgroud)
并找到类型a
,b
并c
为两个功能.
在这种情况下foldMap
,类型是
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
Run Code Online (Sandbox Code Playgroud)
我认为无法将此功能的类型"拆分"为两部分,因此我可以获得"a","b"和"c"类型(.)
.
然后我要求ghci
计算它的类型.它成功了以下类型:
Prelude Data.Foldable> :t foldMap . foldMap
foldMap . foldMap
:: (Foldable t, Foldable t1, Data.Monoid.Monoid m) =>
(a -> m) -> t (t1 a) -> m …
Run Code Online (Sandbox Code Playgroud) 在Web,Scotty:连接池作为monad阅读器的问题中,它显示了如何使用在堆栈中ScottyT
嵌入Reader
monad来访问静态配置(在这种情况下,连接池).
我有一个类似的问题,但更简单 - 或者至少我是这么认为的......
我想添加一个Reader
处理程序(即a ActionT
),而不是整个应用程序.
我开始从上面的问题修改程序,但我无法弄清楚如何ActionT Text (ReaderT String IO)
转换成ActionT Text IO
处理程序需要.在摸索并试图使用打字孔希望看到如何构建这个之后我不得不放弃现在并寻求帮助.我真的觉得这应该很简单,但无法弄清楚如何做到这一点.
这是程序,我被卡住的行突出显示:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text.Lazy as T
import Data.Text.Lazy (Text)
import Control.Monad.Reader
import Web.Scotty.Trans
type ActionD = ActionT Text (ReaderT String IO)
main :: IO ()
main = do
scottyT 3000 id id app
-- Application
app :: ScottyT Text IO ()
app = do
get "/foo" $ do …
Run Code Online (Sandbox Code Playgroud) 我最近备份了我即将过期的大学主目录,将其作为 tar 流发送并在我的端进行压缩:ssh user@host "tar cf - my_dir/" | bzip2 > uni_backup.tar.bz2
.
这让我思考:我只知道压缩如何工作的基础知识,但我想这种压缩数据流的能力会导致较差的压缩,因为算法需要在某个时刻完成处理数据块,写下这个到输出流并继续下一个块。
\n\n是这样吗?或者这些程序只是将大量数据读入内存,压缩它,写入它,然后再重复一遍?或者这些 \xe2\x80\x9cstream 压缩器\xe2\x80\x9d 中是否使用了任何巧妙的技巧?我看到bzip2和xz的手册页都讨论了内存使用情况,并且man bzip2还暗示了这样一个事实:将要压缩的数据切割成块时几乎不会丢失:
\n\n\n\n\n较大的区块大小会导致边际收益迅速递减。大多数压缩来自块大小的前两三百 k,在小型机器上使用 bzip2 时值得记住这一事实。同样重要的是要认识到,解压缩内存要求是在压缩时通过选择块大小来设置的。
\n
我仍然很想知道是否使用了其他技巧,或者我可以在哪里阅读更多相关内容。
\n我目前正在Elm中构建一个Web应用程序的一个小组件.elm组件被编译为JavaScript文件,加载然后安装在DOM节点上.然后应该从中读取配置对象window.config
.(这不是我可以改变的.)
我怎样才能读取一个字符串,window.config.title
以便在我的Elm组件中使用?我看过端口,但它似乎要求我修改生成的JavaScript或包装它周围的东西.这是唯一的选择吗?如果是这样,我怎么才能简单地读取变量的值?
haskell ×7
types ×3
assembly ×1
bzip2 ×1
compression ×1
elm ×1
gcc ×1
glibc ×1
io-monad ×1
javascript ×1
linux ×1
maybe ×1
ml ×1
monads ×1
performance ×1
scotty ×1
servant ×1
space-leak ×1
stream ×1
xz ×1