我正在尝试使用Parsec编写一个解析器,它将解析有文化的Haskell文件,如下所示:
The classic 'Hello, world' program.
\begin{code}
main = putStrLn "Hello, world"
\end{code}
More text.
Run Code Online (Sandbox Code Playgroud)
我写了以下内容,受到RWH中的例子的启发:
import Text.ParserCombinators.Parsec
main
= do contents <- readFile "hello.lhs"
let results = parseLiterate contents
print results
data Element
= Text String
| Haskell String
deriving (Show)
parseLiterate :: String -> Either ParseError [Element]
parseLiterate input
= parse literateFile "(unknown)" input
literateFile
= many codeOrProse
codeOrProse
= code <|> prose
code
= do eol
string "\\begin{code}"
eol
content <- many anyChar
eol
string "\\end{code}"
eol …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过编写小程序来学习Haskell ...所以我正在为简单的表达式编写词法分析器/解析器.(是的,我可以使用Alex/Happy ......但我想先学习核心语言).
我的解析器本质上是一组构建树的递归函数.在语法错误的情况下,我通常会抛出一个异常(即如果我是用C#编写的),但在Haskell中似乎不鼓励这样做.
那么替代方案是什么?我真的不想在解析器的每一位中测试错误状态.我希望最终得到一个有效的节点树,或者带有详细信息的错误状态.
考虑我写的以下代码:
import Control.Monad
increasing :: Integer -> [Integer]
increasing n
| n == 1 = [1..9]
| otherwise = do let ps = increasing (n - 1)
let last = liftM2 mod ps [10]
let next = liftM2 (*) ps [10]
alternateEndings next last
where alternateEndings xs ys = concat $ zipWith alts xs ys
alts x y = liftM2 (+) [x] [y..9]
Run Code Online (Sandbox Code Playgroud)
' increasing n'应返回一个n位数字列表,其数字从左到右增加(或保持不变).
有没有办法简化这个?使用' let'和' liftM2'到处都看起来很难看.我想我错过了关于列表monad的重要内容,但我似乎无法摆脱它们.
我正在尝试在Haskell中编写一个简单的光线跟踪器.我想定义一个类型类,表示可用的各种表面,并有一个函数来确定光线与它们相交的位置:
{-# LANGUAGE RankNTypes #-}
data Vector = Vector Double Double Double
data Ray = Ray Vector Vector
class Surface s where
intersections :: s -> Ray -> [Vector]
-- Obviously there would be some concrete surface implementations here...
data Renderable = Renderable
{ surface :: (Surface s) => s
, otherStuff :: Int
}
getRenderableIntersections :: Renderable -> Ray -> [Vector]
getRenderableIntersections re ra = intersections (surface re) ra
Run Code Online (Sandbox Code Playgroud)
但是这给了我错误:
Ambiguous type variable 's' in the constraint:
'Surface'
arising …Run Code Online (Sandbox Code Playgroud) 我正在尝试为Project Euler问题#145编写一个强力解决方案,我无法让我的解决方案在不到1分30秒的时间内运行.
(我知道有各种捷径,甚至是纸笔解决方案;出于这个问题的目的,我不考虑那些).
在迄今为止我提出的最佳版本中,分析显示大部分时间都花在了foldDigits.这个函数根本不需要是懒惰的,在我看来应该优化到一个简单的循环.正如你所看到的,我试图使程序的各个部分严格.
所以我的问题是:在不改变整体算法的情况下,是否有某种方法可以将该程序的执行时间降低到亚分钟?
(或者,如果没有,有没有办法看到代码foldDigits尽可能优化?)
-- ghc -O3 -threaded Euler-145.hs && Euler-145.exe +RTS -N4
{-# LANGUAGE BangPatterns #-}
import Control.Parallel.Strategies
foldDigits :: (a -> Int -> a) -> a -> Int -> a
foldDigits f !acc !n
| n < 10 = i
| otherwise = foldDigits f i d
where (d, m) = n `quotRem` 10
!i = f acc m
reverseNumber :: Int -> Int
reverseNumber !n
= foldDigits accumulate …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Scotty来构建一个非常简单的API.我想扩展Scotty monad,以便我的路由处理程序操作能够访问一个不变的环境.我相信这样做的方法是Reader在堆栈中添加一个monad.现在我只想传递一些Text数据.
我把Scotty monads扩展如下:
type BrandyScottyM = ScottyT TL.Text (ReaderT T.Text IO)
type BrandyActionM = ActionT TL.Text (ReaderT T.Text IO)
Run Code Online (Sandbox Code Playgroud)
https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Core.hs
所以我的第一个问题是,这是正确的方法吗?
我已经成功地改变了我的路由处理程序的类型,但我无法弄清楚如何使用这个堆栈启动Scotty.我尝试过以下方法:
runScotty :: Port -> Text -> BrandyScottyM () -> IO ()
runScotty port file = T.scottyT port ((\f -> runReader f file)) id
Run Code Online (Sandbox Code Playgroud)
https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Main.hs
但我得到错误:
Couldn't match type `IO' with `Data.Functor.Identity.Identity'
Expected type: Reader Text (IO a)
Actual type: ReaderT Text IO a
In the first argument of `runReader', namely `f'
In the …Run Code Online (Sandbox Code Playgroud) 我正在使用Persistent编写一些数据访问例程.我希望我的API可以用代表JSON的数据类型来定义,但是在持久性方面,我的数据类型是由持久化的模板系统定义的.
鉴于我有从json到数据库数据类型的映射,反之亦然,我认为我应该能够编写通用数据访问例程.
一切顺利,直到我尝试编写插入函数:
standardInsert :: forall d . forall j .
(PersistEntityBackend d ~ SqlBackend, PersistEntity d, SimpleJsonDataAccessConversion j d)
=> j -> DatabaseEnvironmentT (Maybe (WithId j))
standardInsert json = do
maybeId <- runSqlMaybe $ insert db
return $ toApi <$> maybeId
where db = jsonToDataAccess json :: d -- Scoped type variable here.
toApi key = addId key $ dataAccessToJson db
Run Code Online (Sandbox Code Playgroud)
(j是JSON数据类型d的类型变量,是持久数据类型的类型变量).
这个函数有两个类型变量,j和d,但只j能够从参数中推断出来.
换句话说,如果我调用standardInsert jsonValue,则类型变量d是不明确的. …
是否存在用于混淆JavaScript的.Net组件?我正在动态生成JavaScript并通过ClientScript.RegisterClientScriptBlock发出.我想让其他人更难以查看和修改该脚本.
注意事项:
谢谢!
假设我有一个函数,它采用某种形式的谓词:
void Foo( boost::function<bool(int,int,int)> predicate );
Run Code Online (Sandbox Code Playgroud)
如果我想用一个总是返回true的谓词来调用它,我可以定义一个辅助函数:
bool AlwaysTrue( int, int, int ) { return true; }
...
Foo( boost::bind( AlwaysTrue ) );
Run Code Online (Sandbox Code Playgroud)
但是无论如何调用这个函数(可能使用boost :: lambda)而不必定义一个单独的函数?
[编辑:忘了说:我不能使用C++ 0x]
架构ARM9.编程语言C.
我们有一个第三方堆栈,其中一个调用将一个指针(pBuffer)带到一个内存位置.在堆栈中,它们可以自由地移动指针传递并按照自己的意愿访问它.不幸的是,它们偏移了传入的指针并将其传递给另一个试图从奇数/未计数内存位置执行此操作的函数
((uint16 *)pBuffer)[index] = value;
Run Code Online (Sandbox Code Playgroud)
where value是类型,uint16并index检查边界和索引pBuffer.这会导致未对齐的内存访问异常.pBuffer指向char *堆上.
如上所述,即使我们可以查看第三方堆栈,我们也无法正式更新代码.因此,我们通知提供商,他们在下一版本中提供更新.
我想知道是否有解决方法.如何在不违反未对齐访问的情况下执行上述分配?解决此类问题的最佳方法是什么?
我有一个长时间运行的过程forkIO'd,它产生像素颜色值:
takesAgesToRun :: [[Color]]
myForkedProcess :: IORef [[Color]] -> IO ()
myForkedProcess ref = do let colors = takesAgesToRun
writeIORef ref colors
Run Code Online (Sandbox Code Playgroud)
(其中Color只包含三个Double值).
正如预期的那样,当读取"另一侧"时IORef,存储的值只是一个thunk,因此会阻止主进程.
我知道我需要完全评估[[Color]]正常形式的值,但似乎有两种方法可以实现这一点,而且,我不确定如何将其合并到我的代码中.
我该怎么做?我是否使用rnf,deepSeq或其他一些线程策略?这些是其中一个首选,其他人是否已被弃用?它如何适合我的代码?
(PS请忽略这样一个事实,即将图像存储为颜色列表列表是愚蠢的 - 这只是代码的简化版本).
假设我有一个用于获取数据的接口,以及它的实现:
interface IResourceProvider
{
string Get( Uri uri );
}
class HttpResourceProvider : IResourceProvider
{
public string Get( Uri uri )
{
// Download via HTTP.
}
}
Run Code Online (Sandbox Code Playgroud)
我可以在Castle Windsor注册,如下:
container.Register
( Component.For<IResourceProvider>().ImplementedBy<HttpResourceProvider>()
);
Run Code Online (Sandbox Code Playgroud)
(这都很好).
如果我然后决定我想要一个缓存实现如下:
class CachingResourceProvider : IResourceProvider
{
public CachingResourceProvider( IResourceProvider resourceProvider )
{
_resourceProvider = resourceProvider;
}
public string Get( Uri uri )
{
// Return from cache if it exists.
// Otherwise use _resourceProvider and add to cache.
}
private readonly IResourceProvider _resourceProvider;
}
Run Code Online (Sandbox Code Playgroud)
我如何注册这些嵌套的依赖项? …
(如果我的术语有误,请道歉).
我正在尝试编写一个处理异常的包装函数:如果给定的IO操作抛出,它返回Nothing(IO当然在上下文中),但如果给定的IO操作成功,则返回Just v.
tryMaybe :: IO a -> IO (Maybe a)
tryMaybe action = do
result <- (try action) :: IO (Either SomeException a)
return $ case result of
Left _ -> Nothing
Right v -> Just v
Run Code Online (Sandbox Code Playgroud)
这导致编译器错误消息:
Couldn't match type `a' with `a1'
`a' is a rigid type variable bound by
the type signature for tryMaybe :: IO a -> IO (Maybe a)
at src/Database.hs:33:13
`a1' is a …Run Code Online (Sandbox Code Playgroud) haskell ×9
c++ ×2
arm ×1
boost ×1
c ×1
c# ×1
c++03 ×1
components ×1
embedded ×1
ioref ×1
javascript ×1
lambda ×1
list ×1
monads ×1
nested ×1
obfuscation ×1
parsec ×1
performance ×1
recursion ×1
scotty ×1