haskell 将不同类型转换为字符串

2g32fytz  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(174)

我们的目标是建立一个程序,以人类可读的格式报告特定股票的交易。例如,对于我们的测试数据集,股票VTI的交易将打印为:

Bought 100 units of VTI for 1104 pounds each on day 1

Bought 50 units of VTI for 1223 pounds each on day 5

Sold 150 units of VTI for 1240 pounds each on day 9

下面是测试事务代码:

type Transaction = (Char, Int, Int, String, Int) 

test_log :: [Transaction]
test_log = [('B', 100, 1104,  "VTI",  1),
            ('B', 200,   36, "ONEQ",  3),
            ('B',  50, 1223,  "VTI",  5),
            ('S', 150, 1240,  "VTI",  9),
            ('B', 100,  229, "IWRD", 10),
            ('S', 200,   32, "ONEQ", 11), 
            ('S', 100,  210, "IWRD", 12)
            ]

为此,我认为最好将每个部分拆分为切片,在最后可以将它们连接起来。

--Converting transaction to string

transaction_to_string :: Transaction -> String
transaction_to_string (action: units: stocks: price: day) = 
    let display = action ++ "Bought"
        slice1 = units ++ "of"
        slice2 = stocks ++ "for"
        slice3 = price ++ "on day"
        slice4 = day
    in
        slice1 ++ slice2 ++ slice3 + slice4

我收到的错误是这样的。它给出了一个类型错误,但我不确定为什么,因为在顶部使用的类型函数:

• Couldn't match type ‘[Char]’ with ‘Char’
      Expected: [Char]
        Actual: [[Char]]
    • In the second argument of ‘(++)’, namely ‘slice4’
      In the second argument of ‘(++)’, namely ‘slice3 ++ slice4’
      In the second argument of ‘(++)’, namely
        ‘slice2 ++ slice3 ++ slice4’
   |
   |         slice1 ++ slice2 ++ slice3 ++ slice4
olhwl3o2

olhwl3o21#

第一次尝试:

transaction_to_string :: Transaction -> String
transaction_to_string (action, units, stocks, price, day) = 
                   -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tuple, not list
    let display = show action ++ "Bought" -- << convert non-strings using `show`
        slice1 = show units ++ "of"       -- <<
        slice2 = show stocks ++ "for"     -- <<
        slice3 = price ++ "on day"
        slice4 = show day                 -- <<
    in
        display ++ slice1 ++ slice2 ++ slice3 ++ slice4

您可以通过以下方法来改善此问题:

  • 在正确的位置添加空格
  • 更好地格式化字符串:连接的顺序似乎有点不对(测试一下!)
  • 正确处理display,可以使用如下代码:
let display | action == 'B' = "Bought"
              | action == 'S' = "Sold"
              | otherwise     = "Uhh.. what?"
kkbh8khc

kkbh8khc2#

假设Transaction不是一个类型同义词,理想情况下,你应该让它成为Show的一个示例。

data Transaction = Transaction {
  action :: Char,
  units :: Int,
  stocks :: String,
  price :: Int,
  day :: Int
}

instance Show Transaction where
  show (Transaction {action=a, units=u, stocks=s, price=p, day=d}) = str
    where
      a' = case a of 
        'B' -> "Bought"
        'S' -> "Sold"
        _ -> "Unknown action"
      str = a' ++ " " ++ show u ++ " units of " ++ s ++ 
            " at $" ++ show p ++ " on day " ++ show d

现在:

Prelude> Transaction {action='B', units=100, stocks="FOO", price=56, day=7}
Bought 100 units of FOO at $56 on day 7

相关问题