小编och*_*les的帖子

是什么导致我的Wavefront Obj解析器消耗的内存比输入多10倍?

我正在尝试为Wavefront .obj文件格式编写一个解析器,这是一种非常愚蠢的基于行的格式.希望维基百科文章应该总结它是如何工作的,但基本上你有行记录顶点,普通和其他数组中的条目.最后,面定义是这些单独数组中的三个(或更多)索引.

我的解析器是

{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module WavefrontObj where

import Control.Applicative
import Data.Attoparsec.Text
import Data.Foldable (toList)
import Data.List (foldl')
import Data.List.Split
import Data.Monoid
import Data.NonEmpty ((!:))
import Data.Sequence (Seq)
import Geometry
import Graphics.GL
import Linear
import Linear.Affine
import qualified Data.Sequence as Seq

data Obj =
  Obj {objVertices :: !(Seq (V3 Double))
      ,objNormals :: !(Seq (V3 Double))
      ,objFaces :: !(Seq (V2 (V3 Int)))}
  deriving (Show)

instance Monoid Obj where
  mempty = Obj mempty …
Run Code Online (Sandbox Code Playgroud)

performance parsing haskell memory-leaks

10
推荐指数
1
解决办法
111
查看次数

如何以与其他语言中的mixins/method modifiers/traits类似的方式提升代码重用?

我正在研究一些与数据库模式接口的代码,该数据库模式为持久性图形建模.在我详细讨论我的具体问题之前,我认为可能有助于提供一些动力.我的架构围绕书籍,人物和作者角色.一本书有许多作者角色,每个角色都有一个人.但是,您必须创建新书并对新版本进行修改,而不是允许对书籍对象进行直接UPDATE查询.

现在,回到Haskell的土地上.我目前正在使用几个类型类,但重要的是我有HasRolesEntity:

class HasRoles a where
    -- Get all roles for a specific 'a'
    getRoles :: a -> IO [Role]

class Entity a where
    -- Update an entity with a new entity. Return the new entity.
    update :: a -> a -> IO a
Run Code Online (Sandbox Code Playgroud)

这是我的问题.在更新图书时,您需要创建新图书版本,但需要复制以前的图书角色(否则会丢失数据).最简单的方法是:

instance Entity Book where
    update orig newV = insertVersion V >>= copyBookRoles orig
Run Code Online (Sandbox Code Playgroud)

这是好的,但有一些困扰我,这就是缺乏不变,如果事情是任何担保Entity HasRoles,然后插入一个新的版本将复制在现有的角色.我想到了两个选择:

使用更多类型

一个'解决方案'是介绍RequiresMoreWork a b.从上面开始,insertVersion现在返回一个HasRoles w => …

code-reuse haskell

9
推荐指数
1
解决办法
513
查看次数

如何将Unix POSIX文件描述符或标准输入句柄转换为Socket?

inetdsystemd类型的系统中,系统可以绑定套接字并使用已经存在的套接字启动应用程序,例如提供基于套接字的服务启动.我想在我的一个Haskell守护进程中利用这个功能.

守护进程目前呼吁,socket,bindSocket,listen创建一个Socket对象,我以后可以叫accept上.要将此更改为inetd类型系统,我需要使用标准输入作为a Socket,但到目前为止我能找到的是stdin :: Handle,或者fdToHandle :: CInt -> Handle- 我都不需要.

我似乎无法找到任何类型的东西,也不会找到任何Handle -> Socket类似的东西stdin :: Socket.我能找到的最近的mkSocket是非常低级的,并且大多数其他语言(即Ruby)提供调用以将文件描述符转换为套接字而不必指定各种其他参数.

networking haskell posix inetd systemd

8
推荐指数
1
解决办法
801
查看次数

如何使用GADT限制约束?

我有以下代码,我希望这样的类型检查失败:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}

import Control.Lens

data GADT e a where
  One :: Greet e => String -> GADT e String
  Two :: Increment e => Int -> GADT e Int

class Greet a where
  _Greet :: Prism' a String

class Increment a where
  _Increment :: Prism' a Int

instance Greet (Either String Int) where
  _Greet = _Left

instance Increment (Either String Int) where
  _Increment = _Right

run :: …
Run Code Online (Sandbox Code Playgroud)

haskell gadt

8
推荐指数
1
解决办法
199
查看次数

为什么这个GADT上的模式匹配似乎会在类型检查器中引入歧义?

我正在尝试实现一种抽象语法图形,如Andres Loeh和Bruno C. d所述.S. Oliveira.在大多数情况下,我似乎正确地理解了事情.但是,当我尝试将letrec引入我的语法时,我遇到了一些问题.我认为通过这个小代码示例更容易:

首先,一点前奏:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
import Control.Applicative

infixr 8 :::
data TList :: (k -> *) -> [k] -> * where
  TNil :: TList f '[]
  (:::) :: f t -> TList f ts -> TList f (t ': ts)

tmap :: (forall a. f a -> g a) -> TList …
Run Code Online (Sandbox Code Playgroud)

haskell

8
推荐指数
1
解决办法
209
查看次数

是否可以为此DataKinds支持的异构列表实现删除OverlappingInstances?

随着最近关于HaskellDB的帖子,我一直有动力再次研究HList.正如我们现在-XDataKinds在GHC中实际上有一个异构列表的例子,我想调查HLists如何看待DataKinds.到目前为止,我有以下内容:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

import Data.Tagged

data Record :: [*] -> * where
  RNil :: Record '[]
  (:*:) :: Tagged f (FieldV f) -> Record t -> Record (f ': t)

type family FieldV a :: *

emptyRecord = RNil

(=:) :: (v ~ FieldV f) => f -> v -> Tagged f …
Run Code Online (Sandbox Code Playgroud)

haskell hlist

7
推荐指数
1
解决办法
218
查看次数

是否可以在IO以外的monad中使用带有测试框架的HUnit?

我目前有以下测试代码:

testUpdate :: Test
testUpdate = testCase "update does change artist" $ do
  (created, Just revised, parents) <- mbTest $ do
    Just editor <- fmap entityRef <$> findEditorByName "acid2"

    created <- create editor startWith
    let artistId = coreMbid created

    newRev <- update editor (coreRevision created) expected

    editId <- openEdit
    includeRevision editId newRev
    apply editId

    found <- findLatest artistId
    parents <- revisionParents newRev

    return (created, found, parents)

  coreData revised @?= expected

  assertBool "The old revision is a direct parent of the …
Run Code Online (Sandbox Code Playgroud)

haskell hunit

7
推荐指数
1
解决办法
388
查看次数

如何使用绑定库捕获不同的范围?

我正在尝试使用爱德华的bound库来模拟游戏中的关卡图形 - 至少是在表现形式存储的级别,然后才能实现为OpenGL对象.

一个级别由一堆顶点组成,我们可以在顶点对之间形成一个墙.顶点也用于创建简单的多边形 - 扇区(房间).一个部门拥有墙壁,但也有一些材料属性.顶点,墙壁,扇区和材料之间有很多共享,所以为了利用这种类似图形的特性,我转向了bound库.

到目前为止的代码是,

-- Vertices live alone and aren't influenced by anything else. Perhaps these
-- should still be a functor, but act like Const?
data Vertex = Vertex
  { vertexPos :: V2 CFloat }

-- Textures also live alone, and are simply a wrapper around the path to the 
-- texture.
data Texture = Texture
  { texturePath :: FilePath }

-- A Material needs to refer to one (or more) textures. …
Run Code Online (Sandbox Code Playgroud)

haskell

7
推荐指数
0
解决办法
199
查看次数

对于更安全类型的DSL,可绑定仿函数是一个有用的抽象吗?

动机

我目前正在开发一个小业余爱好项目,尝试在Haskell中实现类似TaskJuggler的功能,主要是作为编写域特定语言的实验.

我目前的目标是建立一个小型DSL来构建a的描述Project,以及它的关联Task.虽然这将是我的下一个扩展,但还没有层次结构.目前,我有以下数据类型:

data Project = Project { projectName :: Text
                       , projectStart :: Day
                       , projectEnd :: Day
                       , projectMaxHoursPerDay :: Int
                       , projectTasks :: [Task]
                       }
  deriving (Eq, Show)

data Task = Task { taskName :: Text }
  deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

那里没什么太疯狂的,我相信你会同意的.

现在我想创建一个DSL来构建项目/任务.我可以使用Writer [Task]monad来构建任务,但这不会很好地扩展.我们现在可以做到以下几点:

project "LambdaBook" startDate endDate $ do
  task "Web site"
  task "Marketing"
Run Code Online (Sandbox Code Playgroud)

where project :: Text -> Date -> Date -> Writer [Task] a,运行Writer以获取任务列表,并选择默认值,例如8 …

monads dsl haskell

6
推荐指数
1
解决办法
312
查看次数

在反应香蕉中执行单个开关

我正在构建一个多模态编辑器reactive-banana- 并且在大多数情况下它是完美的.为了扩展我的场景,编辑器是一些映射软件,或者您可以将其视为一个非常简单的矢量图形编辑器.它目前有两种状态 - 选择模式多边形创建模式.在选择模式下,用户可以使用鼠标右键选择以前创建的多边形(理论上可以将您带到新选择的模式),也可以使用鼠标左键开始创建新的多边形.

目的是,当按下鼠标左键时,我们从选择模式切换到多边形创建模式.在此模式下,鼠标左键表示"添加新顶点",直到用户返回到原始顶点.此时,它们已关闭多边形,因此我们返回选择模式.

我已经实现了几种不同的方式,最近注意到事件切换几乎使这个非常优雅.我可以有:

defaultMode :: Frameworks t => HadoomGUI -> Moment t (Behavior t Diagram)
defaultMode gui@HadoomGUI{..} =
  do mouseMoved <- registerMotionNotify guiMap
     mouseClicked <- registerMouseClicked guiMap
     let lmbClicked = ...
         gridCoords = ...
         diagram = ... 
     switchToCreateSector <- execute ((\m ->
                                         FrameworksMoment
                                           (=<< trimB =<< createSectorMode gui emptySectorBuilder m)) <$>
                                      (gridCoords <@ lmbClicked))
     return (switchB diagram switchToCreateSector)
Run Code Online (Sandbox Code Playgroud)

随着

createSectorMode :: Frameworks t
                 => HadoomGUI
                 -> SectorBuilder
                 -> Point V2 …
Run Code Online (Sandbox Code Playgroud)

haskell reactive-banana

6
推荐指数
1
解决办法
188
查看次数