Haskell에서 문자열을 정수 / 부동으로 변환 하시겠습니까?
data GroceryItem = CartItem ItemName Price Quantity | StockItem ItemName Price Quantity
makeGroceryItem :: String -> Float -> Int -> GroceryItem
makeGroceryItem name price quantity = CartItem name price quantity
I want to create a `GroceryItem` when using a `String` or `[String]`
createGroceryItem :: [String] -> GroceryItem
createGroceryItem (a:b:c) = makeGroceryItem a b c
입력은 ["Apple","15.00","5"]
Haskell의 words
기능을 사용하여 분리 한 형식 입니다 .
나는 때문에 생각 다음과 같은 오류 얻을 makeGroceryItem
수용 Float
과를 Int
.
*Type error in application
*** Expression : makeGroceryItem a read b read c
*** Term : makeGroceryItem
*** Type : String -> Float -> Int -> GroceryItem
*** Does not match : a -> b -> c -> d -> e -> f*
하지만 어떻게해야합니까 b
및 c
유형 Float
과 Int
각각?
read
문자열을 float 및 int로 구문 분석 할 수 있습니다.
Prelude> :set +t
Prelude> read "123.456" :: Float
123.456
it :: Float
Prelude> read "123456" :: Int
123456
it :: Int
그러나 문제는 (1) 당신의 패턴에 있습니다.
createGroceryItem (a:b:c) = ...
다음 :
은 목록에 요소를 추가하는 (오른쪽 연관) 이항 연산자입니다. 요소의 RHS는 목록이어야합니다. 따라서 표현식이 주어지면 a:b:c
Haskell은 다음 유형을 추론합니다.
a :: String
b :: String
c :: [String]
즉 c
, 문자열 목록으로 간주됩니다. 분명히 그것은 read
String을 기대하는 어떤 함수로도 전달되거나 전달 될 수 없습니다 .
대신에
createGroceryItem [a, b, c] = ...
목록에 정확히 3 개의 항목이 있어야하는 경우 또는
createGroceryItem (a:b:c:xs) = ...
≥3 품목이 허용되는 경우.
또한 (2), 표현
makeGroceryItem a read b read c
makeGroceryItem
5 개의 인수 를 받는 것으로 해석되며 그 중 2 개는 read
함수입니다. 괄호를 사용해야합니다.
makeGroceryItem a (read b) (read c)
이 질문에 이미 답변이 있지만 reads
복구 불가능한 예외로 실패하지 않으므로 훨씬 안전하기 때문에 문자열 변환에 사용하는 것이 좋습니다 .
reads :: (Read a) => String -> [(a, String)]
Prelude> reads "5" :: [(Double, String)]
[(5.0,"")]
Prelude> reads "5ds" :: [(Double, String)]
[(5.0,"ds")]
Prelude> reads "dffd" :: [(Double, String)]
[]
성공하면 reads
정확히 하나의 요소가있는 목록을 반환합니다. 변환 된 값과 변환 할 수없는 추가 문자로 구성된 튜플입니다. 실패 reads
하면 빈 목록을 반환합니다.
성공과 실패에 대한 패턴 매치가 쉽고, 얼굴에 터지지 않습니다!
두가지:
createGroceryItem [a, b, c] = makeGroceryItem a (parse b) (parse c)
-- pattern match error if not exactly 3 items in list
또는 대안으로
createGroceryItem (a : b : c : _) = makeGroceryItem a (parse b) (parse c)
-- pattern match error if fewer than 3 items in list, ignore excess items
:
과 같지 않기 때문 입니다 ++
.
Meanwhile on the right hand side --- the side that's giving you the error message you see --- you have to group expressions using brackets. Otherwise parse
is interpreted as being a value you want to pass to makeGroceryItem
, so the compiler complains when you try to pass 5 arguments to a function that only takes 3 parameters.
filterNumberFromString :: String -> String
filterNumberFromString s =
let allowedString = ['0'..'9'] ++ ['.', ',']
toPoint n
| n == ',' = '.'
| otherwise = n
f = filter (`elem` allowedString) s
d = map toPoint f
in d
convertStringToFloat :: String -> Float
convertStringToFloat s =
let betterString = filterNumberFromString s
asFloat = read betterString :: Float
in asFloat
print (convertStringToFloat "15,00" + 1)
-> prints 16.0
Thats how I solved this task in my project.
참고URL : https://stackoverflow.com/questions/2468410/convert-string-to-integer-float-in-haskell
'IT박스' 카테고리의 다른 글
std :: string을 버퍼로 사용하는 데 단점이 있습니까? (0) | 2020.11.07 |
---|---|
C # 작업 표시 줄의 Windows 7 진행률 표시 줄? (0) | 2020.11.07 |
DateTime.Now.ToString (“yyyy-MM-dd hh : mm : ss”)가 PM 시간 대신 AM 시간을 반환합니까? (0) | 2020.11.07 |
Eclipse Dynamic Web Project에서 web.xml은 어디에 있습니까? (0) | 2020.11.07 |
Hashtable의 제네릭 버전은 무엇입니까? (0) | 2020.11.07 |