0

我有以下两个功能:

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返回 type中[T.Text])检查列表中的空文本,而不是检查列表本身是否为空。

4

1 回答 1

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
于 2015-11-14T21:54:52.683 回答