Haskell:编写一个函数,使其可以被提升到列表上

时间:2015-11-14 20:24:54

标签: haskell lifting

我有以下两个功能:

import qualified Data.Text as T

noneOnEmptyA :: T.Text -> T.Text
noneOnEmptyA txt | T.null txt = "None."
                 | otherwise  = txt


noneOnEmptyB :: [T.Text] -> [T.Text]
noneOnEmptyB txts | null txts = ["None."]
                  | otherwise = txts

是否可以编写单个函数1)完成noneOnEmptyA所做的事情,2)可以解除它以完成noneOnEmptyB所做的事情?问题的关键似乎是noneOnEmptyA检查空文本,而noneOnEmptyB检查空列表;但是,noneOnEmptyA解除了以便对列表进行操作(如在fmap noneOnEmptyA返回类型[T.Text]中)检查列表中的空文本,而不是检查列表本身是否为空。

1 个答案:

答案 0 :(得分:2)

您可以做的一件事是引入类型类Nullable

{-# LANGUAGE OverloadedStrings #-}
module Stackoverflow where

import           Data.Text (Text)
import qualified Data.Text as T
import           Data.Monoid
import           Data.String

class Nullable a where
    isNull :: a -> Bool

instance Nullable Text where
    isNull = T.null

instance IsString a => IsString [a] where
    fromString str = [fromString str]

然后你可以写你的功能

noneOnEmpty :: (Nullable a, IsString a, Monoid a) => a -> a
noneOnEmpty a | isNull a = "None" <> mempty
              | otherwise = a

更新

@DanielWagner指出 - Monoid / mempty / <>部分不是必需的

noneOnEmpty :: (Nullable a, IsString a) => a -> a
noneOnEmpty a | isNull a = "None"
              | otherwise = a