小编Jav*_*ran的帖子

如何在haskell中使用Control.Monad.Writer?

我是函数式编程的新手,最近在Learn You a Haskell学习,但是当我完成本章时,我遇到了以下程序:

import Control.Monad.Writer  

logNumber :: Int -> Writer [String] Int  
logNumber x = Writer (x, ["Got number: " ++ show x])  

multWithLog :: Writer [String] Int  
multWithLog = do  
    a <- logNumber 3  
    b <- logNumber 5  
    return (a*b)
Run Code Online (Sandbox Code Playgroud)

我将这些行保存在.hs文件中,但无法将其导入我的ghci,抱怨:

more1.hs:4:15:
    Not in scope: data constructor `Writer'
    Perhaps you meant `WriterT' (imported from Control.Monad.Writer)
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

我通过":info"命令检查了类型:

Prelude Control.Monad.Writer> :info Writer
type Writer w = WriterT w Data.Functor.Identity.Identity
               -- Defined in …
Run Code Online (Sandbox Code Playgroud)

monads haskell

87
推荐指数
2
解决办法
1万
查看次数

如何使二叉树拉链成为Comonad的一个实例?

我想把二叉树拉链作为comonad的一个实例,但我无法弄清楚如何duplicate正确实现.

这是我的尝试:

{-# LANGUAGE DeriveFunctor #-}
import Data.Function
import Control.Arrow
import Control.Comonad

data BinTree a
    = Leaf a
    | Branch a (BinTree a) (BinTree a)
      deriving (Functor, Show, Eq)

data Dir = L | R
    deriving (Show, Eq)

-- an incomplete binary tree, aka data context
data Partial a = Missing Dir (BinTree a) a
    deriving (Show, Eq, Functor)

-- BTZ for BinTree Zipper
newtype BTZ a = BTZ { getBTZ :: ([Partial a], BinTree a) }
    deriving …
Run Code Online (Sandbox Code Playgroud)

haskell zipper comonad

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

我怎样才能在状态monad中正确添加"撤消"功能?

假设我有一个状态monad,我想对状态进行一些操作,并且可能希望在将来撤消更改.我一般可以这样做得体面吗?

举一个具体的例子,让我们假设状态只是一个Int,操作就是将数字增加一个.

type TestM a = StateT a IO ()

inc :: TestM Int
inc = modify (+ 1)
Run Code Online (Sandbox Code Playgroud)

但是,如果我想跟踪状态的所有历史记录,以防我想要撤消到某个先前的状态,我能想到的最好的方法是将状态包装在堆栈中:对状态的每次修改都会被推送到堆栈,以便我可以通过删除堆栈上的顶部元素来撤消更改.

-- just for showing what's going on
traceState :: (MonadIO m, MonadState s m, Show s) => m a -> m a
traceState m = get >>= liftIO . print >> m

recordDo :: TestM a -> TestM [a]
recordDo m = do
    x <- gets head
    y <- liftIO $ execStateT m x
    modify (y:)

inc' :: …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad

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

在haskell中反转列表

我试图扭转一个列表.

以下是我的代码:

reverseList :: [Int] -> [Int]
reverseList [] = []
reverseList (x:xs) =  x:reverseList xs
Run Code Online (Sandbox Code Playgroud)

最终发生的事情是我最终以相同的顺序返回列表.我甚至有一个如何扭转列表的解决方案,但我想知道我在这里做错了什么?我对haskell很新,所以我认为我应该专注于理解更多,然后我可以轻松解决更多问题.我知道有很多解决方案可以解决这个问题,但我需要更多的帮助来理解我在这段代码中做错了什么.

haskell functional-programming

13
推荐指数
3
解决办法
3万
查看次数

在ad-hoc多态函数和参数多态函数之间进行转换的好方法

我想知道是否有一般方法在ad-hoc多态函数和参数多态函数之间进行转换.换句话说,给定一个ad-hoc多态函数,如何实现其参数对应?反过来呢?

sort,例如,它很容易写sort :: Ord a => [a] -> [a]在以下方面sortBy:

sort :: Ord a => [a] -> [a]
sort = sortBy compare
Run Code Online (Sandbox Code Playgroud)

但另一种方式似乎很棘手,到目前为止,我能做的最好的事情是有点"面向对象":

import qualified Data.List as L

data OrdVal a = OV (a -> a -> Ordering) a

instance Eq (OrdVal a) where
    (OV cmp a) == (OV _ b) = a `cmp` b == EQ

instance Ord (OrdVal a) where
    (OV cmp a) `compare` (OV _ b) = a `cmp` b

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

reflection haskell parametric-polymorphism adhoc-polymorphism

10
推荐指数
2
解决办法
301
查看次数

我如何利用haskell中的State和Writer?

当我浏览LYAH的最后一章并与ListZipper会面时,我给了自己一个使它成为状态monad的任务,以便源代码看起来更清晰如下:

manipList = do
    goForward
    goForward
    goBack
Run Code Online (Sandbox Code Playgroud)

同时,我想通过利用Writer monad保留这个过程的日志,但我不知道如何将这两个Monad组合在一起.

我的解决方案是在状态中保留一个[String],我的源代码是

import Control.Monad
import Control.Monad.State

type ListZipper a = ([a], [a])

-- move focus forward, put previous root into breadcrumbs
goForward :: ListZipper a -> ListZipper a
goForward (x:xs, bs) = (xs, x:bs)

-- move focus back, restore previous root from breadcrumbs
goBack :: ListZipper a -> ListZipper a
goBack (xs, b:bs) = (b:xs, bs)

-- wrap goForward so it becomes a State
goForwardM :: State (ListZipper a) [a] …
Run Code Online (Sandbox Code Playgroud)

monads haskell

9
推荐指数
2
解决办法
1147
查看次数

Haskell 中是否有一种准确的方法来编码 Foo 的元组,其中某些组合是被禁止的?

(提前抱歉,我不知道如何更好地表达这个问题)

假设我有这样的数据类型:

data Foo = A | B
Run Code Online (Sandbox Code Playgroud)

现在我想要一对Foo,带有禁止的约束(A, A)

我可以采用简单的方法,将它们全部列出来,如下所示:

data Foo2 = AB | BA | BB
Run Code Online (Sandbox Code Playgroud)

但正如你所看到的,这很快就会失控:如果我们想要 n 元组怎么办Foo?或者如果有更多的选择怎么办Foo

当然,另一种选择是使用newtype智能构造函数

newtype Foo2 = Foo2 (Foo, Foo)

mkFoo2 xy = Foo2 xy <$ guard (xy /= (A,A))
Run Code Online (Sandbox Code Playgroud)

但这在某种意义上是“不准确的”,因为当我们析构时Foo2,我们总是必须处理实际上无法访问的情况,但编译器没有这样的知识:

...
case v :: Foo2 of
  ...
  Foo2 (A, A) -> error "unreachable"
...
      
Run Code Online (Sandbox Code Playgroud)

我的问题是,是否有更好的方法来准确表示“Foo 的 n 元组,其中某些组合,例如(A,A)(A,B,C)(当n=3)不可能”的想法?

附带问题:减法/求反是代数数据类型中的一件事吗?Foo^n - (forbidden …

haskell algebraic-data-types

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

使用组织同态实现加泰罗尼亚数字的巨大开销

我最近正在探索递归方案,想要找到一些组织同态的用例 - 我认为加泰罗尼亚数字可能是一个有趣的例子(我知道有更好的方法来实现加泰罗尼亚数字,这不是本文的重点问题)。我的想法如下:


import Control.Comonad.Cofree
import Control.Monad
import Data.Foldable
import Data.Function.Memoize (memoFix)
import Data.Functor.Foldable
import GHC.Natural

type Nat = Natural

-- unrelated lines omitted

catalanHisto :: Nat -> Nat
catalanHisto = histo \case
  Nothing ->
    1
  Just fs ->
    let xs = toList fs -- this is line 101 in my original code.
        ys = reverse xs
     in sum $ zipWith (*) xs ys

catalanMemo :: Integer -> Integer
catalanMemo = memoFix \q n ->
  if …
Run Code Online (Sandbox Code Playgroud)

haskell recursion-schemes

8
推荐指数
0
解决办法
174
查看次数

寻求对SICP练习1.5的一些解释

这个问题可以在这里找到.

在书中,我发现正常订单评估的一个描述是:

"另一种评估模型不会在需要它们的值之前评估操作数.相反,它首先将操作数表达式替换为参数,直到它获得仅涉及原始运算符的表达式,然后执行评估."

我还简要地找到了另一种描述:"完全扩展然后减少".

在练习中,我认为定义p是类似的(lambda () (p)),它永远不会扩展到原始操作符,因此永远不会终止.

然而,另一方面,在搜索到这个问题的一些答案之后,似乎正常的订单评估应该终止,因为它只根据需要评估事物,实际上(p)不会被评估.

所以我认为"扩展"和"评估"之间必然存在一些差异,而解释者在这里做的是评估事物.

究竟有什么区别,或者我错过了哪些观点?

另一个问题:我应该说" (p)被评估为(p)"还是" (p)被扩展为(p)"?

lisp scheme sicp

7
推荐指数
2
解决办法
1484
查看次数

是否有命令在emacs中应用hlint建议?

当我编写Haskell代码时,我在emacs中使用flycheck和haskell-hlint,我认为如果我可以通过调用一些emacs程序而不是手动修改代码来应用这些hlint建议会很棒.

如果没有可用的,以防我必须为自己编写此程序:

是否保证hlint输出始终为以下形式:

Found:
  {Text1}
Why not:
  {Text2}
Run Code Online (Sandbox Code Playgroud)

哪里{Text?}可以始终解析为Haskell抽象语法树?

emacs haskell hlint flycheck

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