我是monad的新手,它的使用和使用do语句的以下结构使我很困惑:
pairs xs ys = do x <- xs
y <- ys
return (x, y)
Run Code Online (Sandbox Code Playgroud)
我被告知这应该返回所有可能的x和y对,我不明白,因为我之前教过以下代码:
eval (Val n) = Just n
eval (Div x y) = do n <- eval x
m <- eval y
safediv n m
Run Code Online (Sandbox Code Playgroud)
意思是:执行eval x,然后保持其结果,如果不等于Nothing(否则返回Nothing)as n,然后相同eval y,然后如果两者都没有Nothing,它将进入safediv结合两个结果的最终函数(否则返回Nothing).
但是,函数中第一次使用do语句的pairs工作方式完全不同?
如果有人可以帮我解决这个问题,并解释一下do语句及其结构的实际功能,我们将不胜感激!
最好的问候,Skyfe.
关于点运算符,我有点困惑.我有以下代码(用于测试):
test :: Int -> Int -> Int
test x y = f1 . f2 x y
where f1 n = n+1
f2 x' y' = x' * y'
Run Code Online (Sandbox Code Playgroud)
我认为它将首先执行(f2 xy),然后在该结果上执行f1,但它会抛出错误.谁能告诉我点运算符的确切定义以及等于f1的内容.f2 xy?(在没有点运算符的情况下编写)
最好的问候,Skyfe.
编辑:如果点运算符产生一个完整的新函数,我认为以下代码应该工作:
test :: Int -> Int -> Int
test x y = f1 . f2 x
where f1 n = n+1
f2 x' y' = x' + y'
Run Code Online (Sandbox Code Playgroud)
但是该代码也会返回错误.
有没有办法可以为不同的模式创建一个具有多个定义的函数,包括在没有其他函数的语句模式匹配时执行的函数?
例如:
someFunc (pattern1) = def1
someFunc (pattern2) = def2
someFunc (<otherwise/all other possible values>) = def3
Run Code Online (Sandbox Code Playgroud)
或者,如果这不可能,它怎么能实现?
提前致谢!
最好的问候,Skyfe.
如何为Monoid实例使用以下数据类型?
data Counts = Counts {
binds :: Int,
returns :: Int,
gets :: Int,
puts :: Int
} deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)
我想像这样的东西:
mempty = Counts { 0, 0, 0, 0 }
(Counts { b, r, g, p }) mappend (Counts { b', r', g', p' }) = Counts { (b + b'), (r + r'), (g + g'), (p + p') }
Run Code Online (Sandbox Code Playgroud)
但是这给了我一个'0'的解析错误......也许我完全错了,误解了数据类型/ monoid,但我无法弄明白.如果有人能帮助我,我将不胜感激!
最好的问候,Skyfe.
我正在为我的State Monad实例获得一个<< loop >> Exception,我想这是指一个无限循环,但我看不出我的代码在使用时会如何导致一个:
instance Monad (State' s) where
-- return :: a -> State' s a
return x = State' (\(s,c) -> (x, s, (c <> oneReturn) ))
-- (>>=) :: State' s a -> (a -> State' s b) -> State' s b
st >>= k = State' $ \(s,c) -> let (a, s', c) = runState' st (s,c)
in runState' (k a) (s',(c <> oneBind) )
instance MonadState (State' s) s where
-- get :: State' …Run Code Online (Sandbox Code Playgroud) 我需要通过深度优先顺序遍历来标记二叉树,因此我认为我需要首先遍历树的左侧分支并标记它们,然后对正确的分支执行相同的操作.我的二叉树只在内部节点(而不是在末端节点/叶子)存储值:
label :: MonadState m Int => Tree a -> m (Tree (Int, a))
label (Branch l x r) = do n <- get
l' <- label l
r' <- label r
return (Branch l' (n, x) r')
label (Leaf) = return Leaf
Run Code Online (Sandbox Code Playgroud)
*编辑:需要使用State Monad然而我并没有真正掌握它的用法.我当前的代码如上所示,但无法正常工作.
编辑:所需的结果,例如:
Branch (Branch Leaf (-2) Leaf) 1 Leaf
Run Code Online (Sandbox Code Playgroud)
应该:
Branch (Branch Leaf (0,-2) Leaf) (1,1) Leaf
Run Code Online (Sandbox Code Playgroud)
另外我不确定我应该如何使用State Monad,我仍然对其使用感到困惑:
instance Monad (State' s) where
-- return :: a -> State' s a
return x = State' …Run Code Online (Sandbox Code Playgroud) 我正在尝试将函数映射到 Map (来自Data.Map)实例以将其转换为新类型的 Map。具体来说,我有两种类型的地图:
type Scope = Map.Map String AExpr
type Row = Map.Map String Value
Run Code Online (Sandbox Code Playgroud)
映射AExpr到Value(给定它的第一个参数 Scope )的函数:
evalAExpr :: Scope -> AExpr -> Value
Run Code Online (Sandbox Code Playgroud)
还有一个 type 的实例Scope,比如说x,我想为它映射函数evalAExpr以获得一个 type 的实例Row。
根据文档,这应该可以简单地使用:
map :: (a -> b) -> Map k a -> Map k b
Run Code Online (Sandbox Code Playgroud)
所以在我的情况下,这将是:
x :: Scope
evalAExpr :: Scope -> AExpr -> Value
y = map (evalAExpr x) x :: Row …Run Code Online (Sandbox Code Playgroud) 有没有什么方法可以使用文件的内容,它包含一个计数器值(数据库系统的增量id)作为常规int?
我们正在尝试在Haskell中创建一个小型数据库系统,并需要跟踪表的增量ID.我们认为唯一"简单"的方法是将它们保存在普通的txt文件中.但是,在检索它们时,返回类型将是IO Int.我们的数据库表定义需要一个Intid作为id.
有没有人知道如何使用txt文件中的增量id(或一般的整数值)来获取需要Int值的类实例?
提前致谢!
编辑:说明问题的代码示例:
data SomeTable = SomeTable { id :: Int, testField :: String }
someRow = SomeTable (generateNextId "SomeTable") "Test"
Run Code Online (Sandbox Code Playgroud)
where generateNextId从文件中读取当前增量id(因此具有类型IO Int而不是Int).
haskell ×8
monads ×3
types ×2
casting ×1
database ×1
dictionary ×1
dot-operator ×1
function ×1
int ×1
io ×1
map-function ×1
monoids ×1
state ×1
tree ×1