2015-07-10 90 views
1

我有一個小程序,它採取布爾,數字,字符串中的任何一個,並呈現爲一個字符串。渲染數字,布爾,字符串作爲字符串在haskell失敗

module Main() where 

data Value = Number Int 
     | Bool Bool 
     | String String 
    deriving (Eq, Show) 

renderValue :: Value -> String 
renderValue (String s) = show s 
renderValue(Bool True) = "true" 
renderValue(Number n) = show n 

main = do 
    putStrLn $ renderValue "bye, saravana" 

renderValue是一個重載的方法,應該採取字符串輸入。但最後一行,

putStrLn $ renderValue "bye, saravana" 

打印誤差,

Couldn't match expected type ‘Value’ with actual type ‘[Char]’ 
In the first argument of ‘renderValue’, namely ‘"bye, saravana"’ 
In the second argument of ‘($)’, namely 
    ‘renderValue "bye, saravana"’ 
In a stmt of a 'do' block: putStrLn $ renderValue "bye, saravana" 

爲什麼Value = Number | Bool | String不採取串投入? NumberBoolString

+1

'renderValue'需要一個'Value'參數而你正在嘗試提供一個'String'(它是'[Char]'的別名)。你需要使用'renderValue(String「bye,saravana」)''。 – Lee

+0

@Lee您應該將其作爲答案發布。 – Sibi

+0

我試過了,'renderValue([Char] s)= show s'。它在[Char]上解析錯誤失敗。然後,我試着'導入Data.Char'和'renderValue(Char s:xs)= show s'。它仍然抱怨,'不在範圍內:數據構造函數'Char'' .... –

回答

4

data聲明有三個構造函數一起定義了一個類型Value。你renderValue功能需要一個Value的說法,而在

renderValue "bye, saravana" 

您提供一個String(這是[Char]的別名)的說法。您需要提供一個Value

renderValue (String "bye, saravana") 

你也應該考慮重命名你的構造函數Value,因爲它們與現有的StringBool類型可能會造成一些混亂衝突。

+0

爲什麼Haskell沒有將「bye,saravana」的類型解釋爲String,並調用正確的實現。是不是顯式的將字符串常量強制轉換爲字符串,多餘? –

+1

@MadhavanKumar - 在'renderValue'中,您不是在投射,而是在指定的構造函數'Number','String','Bool'上匹配。那些構造函數還定義了創建「Value」值的函數,例如'Number'是一個函數'Int - > Value'。你不是創建一個可以是'Int','String'或'Bool'的類型,而是創建一個包含'Int','String'或'Bool'的三種情況的類型。我建議你將構造函數重命名爲'VString','VNumber'和'VBool',這可以讓事情變得更加清晰。 – Lee

-1
  1. 請注意,您不需要使用showString情況下,因爲它已經擁有了正確的類型。

  2. 如果您不使用它們,則無需派生ShowEq

  3. 你的代碼Bool False沒有定義的情況下(通過與-Wall編譯驗證),您可以重用的BoolShow實例來處理FalseTrue在同一時間。

下面的代碼:

module Main where 

import Data.Char 

data Value = Number Int 
      | Bool Bool 
      | String String 

renderValue :: Value -> String 
renderValue (String s) = s 
renderValue (Bool b) = toLower <$> show b 
renderValue (Number n) = show n 

main :: IO() 
main = putStrLn $ renderValue $ String "bye, saravana" 

另外,如果你想避免打字String可以使用OverloadedStrings擴展:

{-# LANGUAGE OverloadedStrings #-} 

module Main where 

import Data.Char 
import Data.String 

data Value = Number Int 
      | Bool Bool 
      | String String 

instance IsString Value where 
    fromString = String 

renderValue :: Value -> String 
renderValue (String s) = s 
renderValue (Bool b) = toLower <$> show b 
renderValue (Number n) = show n 

main :: IO() 
main = putStrLn $ renderValue "bye, saravana"