我正在尝试为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) 我正在研究一些与数据库模式接口的代码,该数据库模式为持久性图形建模.在我详细讨论我的具体问题之前,我认为可能有助于提供一些动力.我的架构围绕书籍,人物和作者角色.一本书有许多作者角色,每个角色都有一个人.但是,您必须创建新书并对新版本进行修改,而不是允许对书籍对象进行直接UPDATE查询.
现在,回到Haskell的土地上.我目前正在使用几个类型类,但重要的是我有HasRoles和Entity:
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 => …
在inetd和systemd类型的系统中,系统可以绑定套接字并使用已经存在的套接字启动应用程序,例如提供基于套接字的服务启动.我想在我的一个Haskell守护进程中利用这个功能.
守护进程目前呼吁,socket,bindSocket,listen创建一个Socket对象,我以后可以叫accept上.要将此更改为inetd类型系统,我需要使用标准输入作为a Socket,但到目前为止我能找到的是stdin :: Handle,或者fdToHandle :: CInt -> Handle- 我都不需要.
我似乎无法找到任何类型的东西,也不会找到任何Handle -> Socket类似的东西stdin :: Socket.我能找到的最近的mkSocket是非常低级的,并且大多数其他语言(即Ruby)提供调用以将文件描述符转换为套接字而不必指定各种其他参数.
我有以下代码,我希望这样的类型检查失败:
{-# 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) 我正在尝试实现一种抽象语法图形,如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) 随着最近关于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) 我目前有以下测试代码:
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) 我正在尝试使用爱德华的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中实现类似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 …
我正在构建一个多模态编辑器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 ×10
code-reuse ×1
dsl ×1
gadt ×1
hlist ×1
hunit ×1
inetd ×1
memory-leaks ×1
monads ×1
networking ×1
parsing ×1
performance ×1
posix ×1
systemd ×1