小编Dan*_*ton的帖子

Haskell函数将日期的一部分作为字符串

我有一个关于日期和StringHaskell 的初学者问题.

我需要像String在Haskell中那样获得日期(年,月或日)的一部分.我发现,如果我在GHCi中写下以下两行

Prelude> now <- getCurrentTime
Prelude> let mon = formatTime defaultTimeLocale "%B" now
Run Code Online (Sandbox Code Playgroud)

mon是类型String.但是,我无法将其置于一个功能中.我试过以下内容:

getCurrMonth = do
    now <- getCurrentTime
    putStrLn (formatTime defaultTimeLocale "%B" now)
Run Code Online (Sandbox Code Playgroud)

但这会返回类型IO (),我需要String(也不是IO String,只String).

我理解该do语句创建了一个我不想要的monad,但我一直无法找到任何其他解决方案来获取Haskell中的日期.

那么,有没有办法写这样的函数?

在此先感谢您的帮助!

io monads datetime haskell

6
推荐指数
2
解决办法
2194
查看次数

哈斯克尔有没有态射?

我有一些GADT代表lambda演算中的一个术语.

data Term a = 
      Var a
    | Lambda a (Term a)
    | Apply (Term a) (Term a)
Run Code Online (Sandbox Code Playgroud)

我想要做的是在该类型上有一个通用的转换接口.它应该具有类似于此的类型签名:

(Term a -> Term a) -> Term a -> Term a
Run Code Online (Sandbox Code Playgroud)

编写此函数很容易:

fmap' :: (Term a ? Term a) ? Term a ? Term a 
fmap' f (Var v) = f (Var v)
fmap' f (Lambda v t) = Lambda v (fmap' f t)
fmap' f (Apply t1 t2) = Apply (fmap' f t1) (fmap' f t2)
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是haskell(或haskell库)中有某种通用结构来进行这种转换(类似于Functor它应该叫做态射)?

haskell functional-programming functor

6
推荐指数
2
解决办法
666
查看次数

用箭头比较列表长度

比较列表长度的启发

如果我想在列表列表中找到最长的列表,最简单的方法可能是:

longestList :: [[a]] -> [a]
longestList = maximumBy (comparing length)
Run Code Online (Sandbox Code Playgroud)

一种更有效的方法是预先计算长度:

longest :: [[a]] -> [a]
longest xss = snd $ maximumBy (comparing fst) [(length xs, xs) | xs <- xss]
Run Code Online (Sandbox Code Playgroud)

现在,我想更进一步.对于正常情况,它可能没有效率,但你能用箭头解决这个问题吗?我的想法基本上是,同时逐步浏览所有列表,并继续踩到你超越每个列表的长度,除了最长的.

longest [[1],[1],[1..2^1000],[1],[1]]
Run Code Online (Sandbox Code Playgroud)

在前面(非常人为的)示例中,您只需要在每个列表中执行两个步骤,以确定列表[1..2^1000]是最长的,而无需确定所述列表的整个长度.我是对的,这可以用箭头完成吗?如果是这样,那怎么样?如果没有,那么为什么不,以及如何实施这种方法?

comparison haskell arrows list

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

Variadic列表构造函数,如何默认为正确的类型并获得类型安全性

这是我得到的:

{-# LANGUAGE MultiParamTypeClasses
           , FlexibleInstances #-}

class ListResultMult r a where
  lstM :: a -> [a] -> r

listM :: ListResultMult r a => a -> r
listM a = lstM a []


instance ListResultMult r a => ListResultMult (a -> r) a where
  lstM a as x = lstM x $ a:as

instance ListResultMult [a] a where
  lstM a as = reverse $ a:as
Run Code Online (Sandbox Code Playgroud)

以下是它的工作原理:

> listM 'a' 'b' 'c' :: String
"abc"
> putStrLn $ listM 'a' …
Run Code Online (Sandbox Code Playgroud)

haskell variadic-functions type-safety

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

比计算单位列表的长度更好的方法

我有时发现自己编写这样的代码:

someFunc :: Foo -> Int
someFunc foo = length $ do
  x <- someList
  guard someGuard
  return ()
Run Code Online (Sandbox Code Playgroud)

或等效地:

someFunc foo = length [() | x <- someList, someGuard]
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来执行这种计算?更高效?更具可读性?更惯用吗?

haskell list idiomatic

6
推荐指数
2
解决办法
150
查看次数

自动将函数应用于子结构

假设我在抽象语法树数据类型上编写"替换"函数:

data Term = Id String
          | If Term Term Term
          | Let String Term Term
          ...

subst :: String -- name of identifier to replace
      -> Term   -- term to replace the identifier with
      -> Term   -- body in which to perform the replacements
      -> Term
subst identifier term = go
  where go (Id id') = if identifier == id' then term else Id id'
        go (If t1 t2 t3) = If (go t1) (go t2) (go t3)
        go …
Run Code Online (Sandbox Code Playgroud)

recursion haskell algebraic-data-types

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

这是Scala中更高级的类型吗?

有以下定义

type MyMap = Map[String, List[Map[Int, String]]] 
Run Code Online (Sandbox Code Playgroud)

Map可以定义为更高的kinded类型吗?

types scala type-kinds

6
推荐指数
2
解决办法
296
查看次数

在测试期间访问`beforeAll`设置的值

这是我得到的:

spec :: Spec
spec = do
  manager <- runIO newManager

  it "foo" $ do
    -- code that uses manager

  it "bar" $ do
    -- code that usees manager
Run Code Online (Sandbox Code Playgroud)

对于文档runIO表明,我或许应该使用beforeAll替代,因为我并不需要manager构建规范的树,我只是需要它来运行每个测试,而在我的使用情况下,它的所有份额对他们来说是更好的同一个经理而不是创造每个测试都有一个新的.

如果您不需要IO操作的结果来构造spec树,则beforeAll可能更适合您的用例.

beforeAll :: IO a -> SpecWith a -> Spec
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何从测试中访问管理器.

spec :: Spec
spec = beforeAll newManager go

go :: SpecWith Manager
go = do
  it "foo" $ do
    -- needs "manager" in scope
  it "bar" $ do
    -- …
Run Code Online (Sandbox Code Playgroud)

haskell unit-testing hspec

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

根据类型为通用函数提供不同的函数体

假设我有一些通用功能

genericFunc :: a -> b
genericFunc x = doSomeHardWork
Run Code Online (Sandbox Code Playgroud)

但对于特定类型,可以采用更有效的方式genericFunc.

genericFunc :: ParticularType -> b
genericFunc x = doSomeEasyWork
Run Code Online (Sandbox Code Playgroud)

将这两个函数体组合成相同的最佳方法是什么genericFunc,这样当使用ParticularType它时,它会doSomeEasyWork,但是当用于其他类型时,它会是doSomeHardWork什么?我特别排除了使用不同名称或不同模块的选项.

我相信这可以通过类型类来完成,但我对使用语言编译指示的解决方案更感兴趣.我有一个模糊的暗示,这可以用语言编译,但我不知道如何.如果您比较和对比这些方法和/或任何其他可能的方法,奖励积分.

generics haskell function dynamic-dispatch

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

使ReadArgs 1.0使用单个参数

使用ReadArgs包,它似乎不支持单参数情况.

{-# LANGUAGE ScopedTypeVariables #-}

import ReadArgs (readArgs)

main = do
  (foo :: Int) <- readArgs
  print foo
Run Code Online (Sandbox Code Playgroud)

错误是(使用版本1.0时):

No instance for (ReadArgs.ArgumentTuple Int)
  arising from a use of `readArgs'
Run Code Online (Sandbox Code Playgroud)

我的问题是双重的:

  1. readArgs工作怎么样?
  2. 如何调整该库以允许它使用单个参数?

NB版1.1的ReadArgs消除了这个"错误"; 看评论.

haskell command-line-arguments

5
推荐指数
2
解决办法
170
查看次数