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.)