颠倒类型IO Bool的返回值

时间:2015-09-26 00:19:55

标签: haskell boolean monads functor

我有一个返回类型IO Bool的函数。我想将此函数用作filterM的参数,但我实际想要做的是反转其输出。我已经尝试了(not . f)的效果,但not并不适合IO氛围。如何反转IO Bool

这是一个极小的工作示例:

#!/usr/bin/env runhaskell
{-# LANGUAGE UnicodeSyntax #-}
module Main where
import Prelude.Unicode

userEnteredStr ∷ String → IO Bool
userEnteredStr str = do
    input ← getLine
    return (input ≡ str)

-- doesn't work. How would I write this function? 
--userDidntEnterStr ∷ String → IO Bool
--userDidntEnterStr str = not . userEnteredStr

main = do result ← userEnteredStr "y"
          print result

对不起,如果这是基本的!我无法在类型为IO Bool -> IO Bool的Hoogle上找到某个功能,并且在我的网络搜索中找不到任何内容。

1 个答案:

答案 0 :(得分:5)

为了记录,"没有工作"是不是一个非常有用的错误描述:)这是一个语法错误?类型错误?它编译和类型检查,但返回错误的值?它可能是对你的问题最模糊的描述......对于想要帮助你的人来说,这通常是一个非常大的障碍/障碍。

这里的主要问题是您无法将not应用于IO Bool,因为not仅适用于BoolIO Bool不是Bool,也不是Bool",所以它不起作用也就不足为奇了。这就像试图将(* 2)应用于您的狗一样。你的狗不是一个号码!

但似乎你知道如何处理IO中的符号和绑定,所以也许你可以理解为什么这会起作用?

userDidntEnterStr :: String -> IO Bool
userDidntEnterStr str = do
   didEnter <- userEnteredStr str
   return (not didEnter)

或者,您也可以将(a -> b)应用于IO a结果,以使用IO b获取新的fmap

userDidntEnterStr :: String -> IO Bool
userDidntEnterStr str = fmap not (userEnteredStr str)