Noob용 Vinyl을 사용하여 Haskell에서 확장 가능한 레코드
vinyl를 사용하여 하스켈 내에서 확장 가능한 레코드를 생성하는 방법을 보여 드리겠습니다.이 튜토리얼은 이미 Haskell에 익숙하지만 사용법을 모르는 사람들을 대상으로 합니다
vinyl.우리는 비교로 javascript 객체/typescript 인터페이스를 사용할 것입니다.
메모
프로젝트 설정
stack new learn-vinyl를 사용하여 새 프로젝트를 만듭니다. package.yaml에 추가하십시오: vinyl , microlens Lib.hs에서 이 언어 확장을 추가하십시오.{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
import Data.Vinyl
import Data.Vinyl.Syntax ()
import Lens.Micro
import Data.Text
레코드 정의
레코드Person를 정의해 보겠습니다.
type Person = FieldRec
'[ "name" ::: Text
, "age" ::: Int
, "is_single" ::: Bool
]
이것은 다음 typescript 버전과 동일합니다.
type Person = {
name: string,
age: number,
is_single: boolean
}
기록 구성
Person 유형의 레코드를 구성하려면 다음을 수행합니다.
marcus :: Person
marcus =
#name =:= "Marcus"
<+> #age =:= 58
<+> #is_single =:= False
타이프스크립트 버전:
let marcus : Person =
{
name: "Marcus",
age: 58,
is_single: false
}
경고: vinyl 레코드 필드는 문제에 순서를 적용하므로 잘못된 순서를 입력하면 유형 오류가 발생합니다.
예시:
bad_record :: Person
bad_record =
#age =:= 58
<+> #name =:= "Marcus"
<+> #is_single =:= False
이것은 좋지 않습니다. 운 좋게도 rcast를 사용하여 필드를 재정렬하는 기능이 있습니다.
marcus2 :: Person
marcus2 = rcast $
#age =:= (58 :: Int)
<+> #name =:= ("Marcus" :: Text)
<+> #is_single =:= False
한 가지 나쁜 점은 일부 필드의 유형을 명시적으로 추가해야 한다는 것입니다.
필드 액세스
레코드 필드에 액세스하려면 마이크로렌즈에서 (^.) 연산자를 사용할 수 있습니다.
run :: IO ()
run = do
print (marcus ^. #name)
TS 버전:
console.log(marcus.name)
레코드 필드 설정
run :: IO ()
run = do
let updated_marcus = marcus & #name .~ "Aurelius"
print (updated_marcus ^. #name)
타이프스크립트 버전:
marcus.name = "Aurelius"
console.log(marcus)
중첩 레코드
건설
중첩 레코드를 구성하려면 다음을 추가합니다.
type Empire = FieldRec
'[ "king" ::: Person
, "country" ::: Text
]
rome :: Empire
rome =
#king =:= marcus
<+> #country =:= "Italy"
중첩 필드 액세스
run :: IO ()
run = do
print (rome ^. #king . #name)
타이프스크립트 버전:
console.log(rome.king.name)
중첩 필드 설정
run :: IO ()
run = do
let updated_rome = rome & #king . #name .~ "Aurelius"
print (updated_rome ^. #king . #name)
rome.king.name = "Aurelius"
console.log(rome)
결론
vinyl는 매우 강력한 라이브러리이지만 간단한 자습서가 지연됩니다. 이것이 제가 이 튜토리얼을 만드는 이유입니다.
앞으로는 레코드 하위 집합, 레코드 결합 등에 대해 이야기할 것입니다.
전체 소스 코드:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Lib
( run
) where
import Data.Vinyl
import Data.Vinyl.Syntax ()
import Lens.Micro
import Data.Text
type Person = FieldRec
'[ "name" ::: Text
, "age" ::: Int
, "is_single" ::: Bool
]
type Empire = FieldRec
'[ "king" ::: Person
, "country" ::: Text
]
marcus :: Person
marcus =
#name =:= "Marcus"
<+> #age =:= 58
<+> #is_single =:= False
-- bad_record :: Person
-- bad_record =
-- #age =:= 58
-- <+> #name =:= "Marcus"
-- <+> #is_single =:= False
marcus2 :: Person
marcus2 = rcast $
#age =:= (58 :: Int)
<+> #name =:= ("Marcus" :: Text)
<+> #is_single =:= False
rome :: Empire
rome =
#king =:= marcus
<+> #country =:= "Italy"
run :: IO ()
run = do
print (marcus ^. #name)
let updated_marcus = marcus & #name .~ "Aurelius"
print (updated_marcus ^. #name)
-- Nested
print (rome ^. #king . #name)
let updated_rome = rome & #king . #name .~ "Aurelius"
print (updated_rome ^. #king . #name)
Reference
이 문제에 관하여(Noob용 Vinyl을 사용하여 Haskell에서 확장 가능한 레코드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/soriyeak/extensible-record-in-haskell-using-vinyl-for-noob-1l65
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
type Person = FieldRec
'[ "name" ::: Text
, "age" ::: Int
, "is_single" ::: Bool
]
type Person = {
name: string,
age: number,
is_single: boolean
}
marcus :: Person
marcus =
#name =:= "Marcus"
<+> #age =:= 58
<+> #is_single =:= False
let marcus : Person =
{
name: "Marcus",
age: 58,
is_single: false
}
bad_record :: Person
bad_record =
#age =:= 58
<+> #name =:= "Marcus"
<+> #is_single =:= False
marcus2 :: Person
marcus2 = rcast $
#age =:= (58 :: Int)
<+> #name =:= ("Marcus" :: Text)
<+> #is_single =:= False
run :: IO ()
run = do
print (marcus ^. #name)
console.log(marcus.name)
run :: IO ()
run = do
let updated_marcus = marcus & #name .~ "Aurelius"
print (updated_marcus ^. #name)
marcus.name = "Aurelius"
console.log(marcus)
type Empire = FieldRec
'[ "king" ::: Person
, "country" ::: Text
]
rome :: Empire
rome =
#king =:= marcus
<+> #country =:= "Italy"
run :: IO ()
run = do
print (rome ^. #king . #name)
console.log(rome.king.name)
run :: IO ()
run = do
let updated_rome = rome & #king . #name .~ "Aurelius"
print (updated_rome ^. #king . #name)
rome.king.name = "Aurelius"
console.log(rome)
vinyl는 매우 강력한 라이브러리이지만 간단한 자습서가 지연됩니다. 이것이 제가 이 튜토리얼을 만드는 이유입니다.앞으로는 레코드 하위 집합, 레코드 결합 등에 대해 이야기할 것입니다.
전체 소스 코드:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Lib
( run
) where
import Data.Vinyl
import Data.Vinyl.Syntax ()
import Lens.Micro
import Data.Text
type Person = FieldRec
'[ "name" ::: Text
, "age" ::: Int
, "is_single" ::: Bool
]
type Empire = FieldRec
'[ "king" ::: Person
, "country" ::: Text
]
marcus :: Person
marcus =
#name =:= "Marcus"
<+> #age =:= 58
<+> #is_single =:= False
-- bad_record :: Person
-- bad_record =
-- #age =:= 58
-- <+> #name =:= "Marcus"
-- <+> #is_single =:= False
marcus2 :: Person
marcus2 = rcast $
#age =:= (58 :: Int)
<+> #name =:= ("Marcus" :: Text)
<+> #is_single =:= False
rome :: Empire
rome =
#king =:= marcus
<+> #country =:= "Italy"
run :: IO ()
run = do
print (marcus ^. #name)
let updated_marcus = marcus & #name .~ "Aurelius"
print (updated_marcus ^. #name)
-- Nested
print (rome ^. #king . #name)
let updated_rome = rome & #king . #name .~ "Aurelius"
print (updated_rome ^. #king . #name)
Reference
이 문제에 관하여(Noob용 Vinyl을 사용하여 Haskell에서 확장 가능한 레코드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/soriyeak/extensible-record-in-haskell-using-vinyl-for-noob-1l65텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)