小编lef*_*out的帖子

Monad的最佳实践

我想知道什么可以被视为关于Statemonad 的最佳实践.我也对任何其他建议持开放态度.

我有一个要解析的二进制文件.它包含需要解析的不同标头,以便能够读取整个文件.

因此,只能使用解析中的State来解析头文件.

data ParseState = ParseState {
   offset :: Int64
   buffer :: B.ByteString
   endianness :: Endianness
   pointerSize :: MachineWord
   positionStack :: [Int64]
}
Run Code Online (Sandbox Code Playgroud)

然后将该数据用于Statemonad中

type Parser a = State ParseState a
Run Code Online (Sandbox Code Playgroud)

这可以完美地解决标头的解析.但是,只要我想解析整个文件,我需要标题中的信息才能正确读取文件.

data Header = Header {
    txtOffset :: Int64,
    stringOffset :: Int64
}
Run Code Online (Sandbox Code Playgroud)

我需要标头信息来继续解析文件.

我的想法是使用一个位于前一个状态之上的新状态monad.所以我有一个新的StateT monad:

type ParserFullState a = StateT Header (State ParserState) a
Run Code Online (Sandbox Code Playgroud)

因此,我可以继续使用新的状态转换器构建一整套解析器函数.我也可以采用不同的方式将标题添加到原始ParseState数据中.

我可以看到将标题添加回ParserState以下内容的优点如下:

  1. 解析器函数的返回类型是统一的
  2. 无需调用lift来访问解析器原语.

我能看到的缺点是:

  1. 高级解析器和低级原语之间没有区别.
  2. 我们无法清楚地说明标头何时完全解析或何时不完整.从而使解析器修改更加脆弱.

你的建议是什么?我应该使用状态转换器吗?我应该将标头添加到原始状态还是其他任何情况?

谢谢.

monads haskell state-monad

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

如何在Haskell中实现BST搜索

我正在尝试理解这段代码:

search_bst :: Tree -> String -> Maybe Int 
search_bst Leaf _ = Nothing
search_bst (Node k v l r) sk =
    if sk == k then Just v
    else if sk < k then search_bst l sk
    else search_bst r sk
Run Code Online (Sandbox Code Playgroud)

我可以得到这个概念但是Node k v l r意味着什么?这是否意味着search_bst需要两个参数,第一个是类型的实例Node并且有三个值?

haskell

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

如何处理在Haskell列表推导II中的Maybe类型

我有一个问题,实现一个可能类型列表操作!

我需要做的是:

ljoin [(2,"S"),(1,"J")] [(2,1),(2,2),(3,4)]
     outputs: [(2,"S",Just 1),(2,"S",Just 2),(1,"J",Nothing)]
Run Code Online (Sandbox Code Playgroud)

到目前为止我写的:

ljoin :: Eq a => [(a,b)] -> [(a,c)] -> [(a,b,Maybe c)]
ljoin xs ys = [if xs==ys then (xa, xb, Just yc) else (xa, xb, Nothing) | (xa, xb) <- xs, (ya, yc) <- ys]
Run Code Online (Sandbox Code Playgroud)

哪会产生错误:

Inferred type is not general enough
*** Expression    : ljoin
*** Expected type : Eq a => [(a,b)] -> [(a,c)] -> [(a,b,Maybe c)]
*** Inferred type : Eq a => [(a,b)] -> [(a,b)] -> …
Run Code Online (Sandbox Code Playgroud)

haskell

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

如何在Haskell中进行简单退出?

这是代码:

main :: IO()
main =  do 
{
         putStrLn ("Meniu: ");
         putStrLn ("1. menu 1");
         putStrLn ("2. menu 2");
         putStrLn ("3. menu 3");
         putStrLn ("4. menu 4");
         putStrLn ("5. Exit - Iesire)");
         putStrLn ("-------------------------");
         putStr ("Enter option: ");
         opt <- getLine;
         if(opt == "1") then do
         {
            Code one etc
            main
         }
            else if(opt == "2") then do
         {
            Code 2 etc
            main
         }
            else if(opt == "3") then do
         {
            code 3 etc
            main
         }
         else if(opt == "4") …
Run Code Online (Sandbox Code Playgroud)

haskell

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

lambda抽象ADT的显示实例

所以,我已经定义了lambda数据类型:

data LExpr
    = Variable String         -- variable
    | Apply LExpr LExpr       -- function application
    | Lambda String LExpr     -- Lambda abstraction 
    deriving (Eq, Show)  
Run Code Online (Sandbox Code Playgroud)

现在我想实现Show自己的一个实例.我已经完成了show'大部分工作的功能,但没有使用实例:

 show' :: LExpr -> String
 show' (Variable a) = a
 show' (Apply e1 e2) = "(" ++ show' e1 ++ " " ++ show' e2 ++ ")"                   
 show' (Lambda x e) = "(? " ++ x ++ ". " ++ show' e ++ ")"    
Run Code Online (Sandbox Code Playgroud)

我如何实现它,以获得以下输出而不使用显式show'函数:

Main> (Apply (Lambda …
Run Code Online (Sandbox Code Playgroud)

haskell instance show typeclass

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

如何在列表理解中定义变量?

在哈斯克尔,我可以做

Prelude> [(y*3, y+4) | x<-[0..5], let y=x^2]
[(0,4),(3,5),(12,8),(27,13),(48,20),(75,29)]
Run Code Online (Sandbox Code Playgroud)

Python 中的等效项是什么,无需重复幂运算,正如我需要的那样

>>> [((x**2)*3, (x**2)+4) for x in range(5)]
[(0, 4), (3, 5), (12, 8), (27, 13), (48, 20)]
Run Code Online (Sandbox Code Playgroud)

我当然可以用 lambda 模拟 Haskell 代码,但这感觉不太 Pythonic...

>>> [(lambda y: (y*3, y+4))(x**2) for x in range(5)]
Run Code Online (Sandbox Code Playgroud)

python list-comprehension

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

在Haskell中,如何为此函数提供正确的数字?

我是Haskell的初学者,试用GPipe.

以下代码运行正常:

shader <- compileShader $ do
  primitiveStream <- toPrimitiveStream id
  let transPrims = fmap
        (\(pos,col) -> (perspective (pi/3) 1 1 100 !* pos, col)) 
        primitiveStream
  fragmentStream <- rasterize
        (const (FrontAndBack, ViewPort (V2 0 0) (V2 500 500), DepthRange 0 1))
        transPrims
  drawContextColor (const (ContextColorOption NoBlending (V3 True True True)))
                   fragmentStream
Run Code Online (Sandbox Code Playgroud)

但是,我有2个变量windowWidth和windowHeight(都是Int类型),当我尝试这样做时:

shader <- compileShader $ do
  primitiveStream <- toPrimitiveStream id
  let transPrims = fmap
        (\(pos,col)
         -> (perspective (pi/3) (windowWidth/windowHeight) 1 100 !* pos, col))
        primitiveStream
  fragmentStream <- rasterize
        (const …
Run Code Online (Sandbox Code Playgroud)

haskell

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

将fractional的类型设置为num

有人可以解释为什么这个编译

Prelude> 1 :: Num a => a
Run Code Online (Sandbox Code Playgroud)

而这不是

Prelude> 1.0 :: Num a => a
Run Code Online (Sandbox Code Playgroud)

第二个例子可以使用Fractional,但是Num是超类Fractional.就像它的超类一样Integral.

haskell typeclass

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

Haskell中的"多种类型"

我对函数式编程和Haskell都很陌生,所以我不确定我是否正确地提出了这个问题,或者它是否有意义,但我决定尝试,因为我没有找到任何有用的东西.我基本上试图实现一个可以返回a Int,a String或List 的函数.我知道我可以用它Either来返回两种类型中的一种,但我想返回三种或更多种中的一种.我尝试定义一个新类型,但我卡住了.

data Rets = Int | String | Bool

checkInt :: Rets -> Bool
check x = case x of
    Int x -> True
Run Code Online (Sandbox Code Playgroud)

checkInt应该返回,True如果给出Int,它只是为了测试,但无论如何我包括它.

我知道我的问题很乱,所以我会感谢任何解释.提前致谢!

haskell functional-programming

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

在 Haskell 中使用 Data.Sequence

我编写了一个程序,结果使用列表太慢了,所以我尝试切换到序列。但是,在查看文档后我似乎无法找出正确的语法。

\n\n

到目前为止,我正在尝试使用这个简单的代码来学习:

\n\n
import Control.Monad\nimport qualified Data.Sequence as S\n\nmain :: IO ()\nmain = do \n       let testSeq = S.empty\n       testSeq S.|> 5\n       testSeq S.|> 20\n       testSeq S.|> 3\n       let newSeq = S.update 2 3 testSeq\n       let x = lookup 2 testSeq\n       print x\n
Run Code Online (Sandbox Code Playgroud)\n\n

我已经尝试了一段时间的语法但没有运气,但它仍然有很多错误:

\n\n
test.hs:9:8:\n    Couldn't match expected type \xe2\x80\x98IO a0\xe2\x80\x99\n                with actual type \xe2\x80\x98S.Seq Integer\xe2\x80\x99\n    In a stmt of a 'do' block: testSeq S.|> 5\n    In the expression:\n      do { let testSeq = S.empty;\n           testSeq S.|> …
Run Code Online (Sandbox Code Playgroud)

haskell

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