나는 haskell을 처음 접했고 실제 응용 프로그램을 시도하여 학습에 접근하고 싶었습니다. 구성 요소 중 하나는 ISO 형식 문자열의 날짜를 구성 요소로 구문 분석 할 수 있습니다. 이 Stack Overflow 게시물 은 시작하는 데 도움 이 되었지만 충분하지 않으며 혼란 스럽습니다.
다음 코드가 있습니다.
import System.Locale
import Data.Time
import Data.Time.Format
data IsoDate = IsoDate {
year :: Int
, month :: Int
, day :: Int
} deriving (Show)
parseIsoDate :: String -> IsoDate
parseIsoDate dateString =
IsoDate year month day
where
timeFromString = readTime defaultTimeLocale "%Y %m %d" dateString :: UTCTime
year = 2013
month = 10
day = 31
2013 년 할로윈에는 멋지고 멋집니다. 저는 다음과 같이 연도를 다시 작성했습니다.
year = formatTime defaultTimeLocale "%y" timeFromString
실패 할 것이라는 것을 알았습니다 (를 IsoDate
사용하여 내 유형을 구성 할 수 없음 String
). 그런 다음 문자열을 Int로 읽으려고했습니다.
year = read (formatTime defaultTimeLocale "%y" timeFromString)
다음 응답으로 :
parseIsoDate "2012-12-23"
IsoDate {year = *** Exception: readsTime: bad input "2012-12-23"
이 전환을 시도하는 몇 가지 다른 시도가 있었지만 내가 게시 한 것은 가장 합리적인 시도였습니다. o 다른 시도는 게시하지 않겠습니다.
나는 현재 코드로 작업하는 방법을 알고 싶었습니다 (구문을 배우려고 할 때), 또한 (날짜 파싱이 필수적이기 때문에) 이것을 처리하는 더 좋은 방법 (아마도 가장 관용적)을 알고 싶습니다. 하스켈.
당신이해야 할 일은
parseIsoDate :: String -> Maybe IsoDate
String
당신이 제공하는 모든 것이 유효한 날짜는 아니기 때문 입니다. 이를 구현하면 이미 대부분의 구성 요소를 올바르게 얻었 UTCTime
지만 Day
데이터 구조로 변환 할 수있는 a 를 구문 분석 할 필요는 없다고 생각 합니다.
import Data.Time
data IsoDate = ...
parseIsoDate :: String -> Maybe IsoDate
parseIsoDate str = do julianDay <- parse str
let (y, m, d) = toGregorian julianDay
return $ IsoDate (fromIntegral y) m d
where parse:: String -> Maybe Day
parse = parseTimeM True defaultTimeLocale "%F"
이제 약간의 설명과 조언 :
데이터 유형 IsoDate
을 Integer
수년 동안 사용하도록 변경할 것입니다. 데이터 유형 은 아마도 클 수 있기 때문입니다 (적어도 Int
우주의 나이를보세요). 이것은 또한 toGregorian
a를 변환하는 결과의 선택입니다. Day -> (Integer, Int, Int)
그렇지 않은 경우 제 예에서 볼 수 있듯이 도움 Integer
을 받아 생성 된를으로 변환해야합니다 .Int
fromIntegral
내가 사용하는 구문은 do-syntax for 라고 합니다 Maybe
. 이것은 첫 번째 줄에서 편리하게 모나드 내부의 값을 추출 하고 이름에 바인딩 합니다 julianDay
. 그런 다음 값을 그레고리 안 데이로 변환합니다. 그리고 다시 return
들어 Maybe
갑니다. 첫 번째 단계가 실패하고를 생성하는 경우 Nothing
, 즉 String
그저 멍청이가 있으면 다른 작업이 수행되지 않고 프로그램이 작업을 수행하지 않고 완료됩니다 (게으른 평가의 힘입니다).
RecordWildCards
확장 프로그램을 사용하고있을 수 있다는 사실이 Functor
다음을 수행 할 수 있습니다.
{-# LANGUAGE Record
module MyLib
import Data.Time
data IsoDate = IsoDate { year :: Integer
, month :: Int
, day :: Int}
deriving (Show)
parseIsoDate :: String -> Maybe IsoDate
parseIsoDate str = do (year, month, day) <- toGregorian <$> parse str
return IsoDate{..}
where parse:: String -> Maybe Day
parse = parseTimeM True defaultTimeLocale "%F"
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다