如何在Haskell中使用带参数的函数绘制?

时间:2014-11-01 10:04:53

标签: function haskell higher-order-functions do-notation

我知道在do区块内我可以从monadic中抽取“提取”其内容。例如,如果我有一个带签名的函数:

myFunction :: MyReader (Set Int)

我可以在do块中执行此操作:

mySet <- myFunction

这会给我{I}我想要的Set Int。但是,如果我改变我的功能以便它需要一个参数:

myFunction :: Int -> MyReader (Set Int)

我不能再做我想做的事了:

myFunction' <- myFunction

无法编译错误Couldn't match expected typeProbable cause: ‘myFunction'’ is applied to too few arguments。尝试这样的事情甚至在语法上都不正确:

myFunction' x <- myFunction x

我确实希望myFunction'属于Int -> Set Int类型。我无法弄清楚或找到任何地方如何做我想要的。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

这可能是您正在寻找的:(未经测试)

data MyEnv = MyEnv { myFn :: Int -> Set Int }
type MyReader a = Reader MyEnv a

myFunction :: Int -> MyReader (Set Int)

something = do
     ...
     myFunction' <- reader (\env x -> runReader (myFunction x) env)
     -- here myFunction' :: Int -> Set Int
但是,它有点丑陋,因为它打破了抽象并重建它。也许有一种更清洁的方式,但由于在任意一元化中不可能做同样的事情,我们真的需要以某种方式打破抽象。

你至少可以将辅助细节保存在辅助函数中:

flipReader :: (a -> Reader b c) -> Reader b (a -> c)
flipReader r = reader (\y x -> runReader (r x) y)

然后:

something = do
    ...
    myFunction' <- flipReader myFunction

答案 1 :(得分:0)

这将有效:

result <- myFunction x

基本上,myFunction的类型为a -> MyReader b,因此myFunction x(其中x :: a)的类型为MyReader b。如您所知,您可以使用MyReader b<-获取值,因此上面的表达式可以正常工作。

Haskell“do”符号是一种(非常松散地说)像一种简单的小脚本语言,你可以将“命令”链接在一起(再次,这是非常松散的),并将结果“存储”在“变量”中”

  var1 <- command1
  var2 <- command2 var1

可以读作

  run command1, store the result in var1
  then
  run command2 using var1 as a parameter, store the result in var2

警告...

有许多monad这个类比会破坏,并且完全错误,但在早期,这几乎是初学者一段时间看到的唯一模式。