如何删除自定义haskell show功能中的“ Just”

时间:2019-04-01 01:34:50

标签: haskell

我有一个名为pitch的客户数据结构,带有2个变量note和octave。我需要将字符串转换为音高,以便编写一个函数,该函数将String作为输入,也许将Pitch作为返回值,因为可能存在一些无效的输入。然后我自定义了show函数,当我在ghci中对其进行测试时,它显示为“ Just A2”(A2是音高值)。这是我的代码:

data Pitch     = Pitch { note :: Char, octave :: Int }deriving (Eq)

toPitch :: String -> Maybe Pitch
toPitch str 
    | strlen == 2 && (note >= 'A' && note <= 'G') 
           && (octave >= 1 && octave <= 3) = Just (Pitch note octave)
    | otherwise = Nothing
    where 
        strlen = length str
        note   = head str
        octave = digitToInt (str!!1)

toString :: Maybe Pitch -> String
toString (Just pitch) = [note pitch] ++ [(intToDigit (octave pitch))] 

instance Show Pitch where
    show pitch = toString (Just pitch)

下面是测试结果:

*Main> let pitch = toPitch "A2"
*Main> show pitch
"Just A2"
*Main> 

有人可以告诉我如何在show功能中删除它吗?非常感谢!

1 个答案:

答案 0 :(得分:3)

我认为Maybe Pitch值的字符串表示形式并不是您真正想要的。相反,您需要一个Maybe String值,表示 if 如果您确实有一个Pitch值,则可以得到一个String表示形式,但是如果您有{{ 1}},您仍然会得到Nothing。这仅意味着将Nothing实例用于Functor

这意味着将您的逻辑移到Maybe的{​​{1}}实例中:

Show

您通常对Pitch本身的值不感兴趣;您对自己可能从中提取的instance Show Pitch where show pitch = note pitch : intToDigit (octave pitch) : "" 值感兴趣。这意味着您通常只想提升Maybe Pitch来获得Pitch的值。

show

要清楚一点,如果Maybe String返回>>> show (Pitch 'A' 2) "A2" >>> toPitch "A2" Just (Pitch 'A' 2) >>> fmap show (toPitch "A2") Just "A2" -- not "Just A2" ,那一定是个秀场大战:显然没有合适的默认值可替代。使用toPitch而不是像

这样的部分函数
Nothing

仅强制您的其余代码以适当的方式适应失败的可能性,而不仅仅是在Maybe Pitch无法返回类型toPitch :: String -> Pitch toPitch str | strlen == 2 && (note >= 'A' && note <= 'G') && (octave >= 1 && octave <= 3) = Pitch note octave where strlen = length str note = head str octave = digitToInt (str!!1) 的值时因运行时错误而崩溃。


您可能还想使用解析器库来实现toPitch。例如

Pitch

解析过程更加简单,如果解析器发生故障,您将获得比toPitch更具描述性的内容。