Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

무엇이든 타입 #58

Open
youngkyo0504 opened this issue Jul 31, 2024 · 0 comments
Open

무엇이든 타입 #58

youngkyo0504 opened this issue Jul 31, 2024 · 0 comments

Comments

@youngkyo0504
Copy link
Owner

템플릿 예시입니다.

title:
full_path: src/pages/.md

무엇이든 타입

보편양화타입이라고한다. 어떤 경우에 유용할까?
랜덤한 원소를 반환하는 함수가 있다고 가정하자. T에는 number, string 등등 여러 타입이 모두 올 수 있다.

T randomUniform<T>(List<T> lst){ ... }

아래 코드를 만족하는 ??? 함수는 무엇일까?

void simulate(??? rand){
  Int number = rand(List<Int>(30,20,30))
  String str = rand(List<String>('a','b','c'))
}

List<Int> -> Int는 불가능하다. List<String> -> String도 마찬가지다.
rand의 매개변수에 string이 오면 string으로 추론해야하고
rand의 매개변수에 int가 오면 int로 추론해야한다.
any를 넣어도 안된다. 추론능력을 잃어버린다.

어떤 방법을 써야할까? 아래와 같이 가능할까?

void simulate<T>(T rand(List<T> lst)){
  // 안됨
  Int number = rand(List<Int>(30,20,30))
  String str = rand(List<String>('a','b','c'))
}

안된다. simulate 함수가 제너릭을 가진다고 가정하면, 제너릭은 한 함수당 하나의 타입만 가질 수 있기때문에 문제를 해결할 수 없다.
이를 해결해주는 것이 무엇이든 타입이다. 다음과 같이 사용할 수 있다.

void simulate(forall T.(List<T> => T) rand){
  Int number = rand(List<Int>(30,20,30))
  String str = rand(List<String>('a','b','c'))
}

무엇이든 타입의 값을 만드는 방법은 간단하다.
제너릭 함수 타입이라면 forall T.(List<T> => T)에 할당할 수 있다.

T randomUniform<T>(List<T> lst){ ... }
T randomGeo<T>(List<T> lst){ ... }

하지만 randInt는 할당할 수 없다. randIntList<Int> => Int 타입이기 때문이다.

무엇이든 타입이 없는 언어라도 제너릭 메서드가 있다면 비슷한 코드를 작성할 수 있다.

class RandomUniform {
  T random(List<T> lst){ ... }
}

class RandomGeo {
  T random(List<T> lst){ ... }
}
const r = new RandomUniform()
void simulate({ T rand<T>(List<T>, lst);} r){
    Int number = r.rand(List<Int>(30,20,30))
    String str = r.rand(List<String>('a','b','c'))
}

Typescript에서는 다음과 같이 쓸 수도 있다.

type Rand = <T>(arr: T[]) => T;

function simulate(rand: Rand): void {
  const number = rand([1, 2]);
  const species = rand(["a", "b"]);

  console.log(`Number: ${number}, Species: ${species}`);
}

// 사용 예시
const exampleRand = <T>(arr: T[]): T => {
  const randomIndex = Math.floor(Math.random() * arr.length);
  return arr[randomIndex];
};

simulate(exampleRand);

왜 필요한가?

제너릭 메서드를 사용하면 되는데 무엇이든 타입은 무슨 가치가 있나?
이것은 마치 일급함수의 존재와 비슷하다.
함수를 값으로 볼 수 있는 일급함수 개념은 사실 굳이 없어도된다.
특정 메서드를 가진 객체를 넘기면 되기 때문이다.
하지만 일급함수가 있으면 코드가 더 간결해지고, 더 많은 기능을 제공할 수 있다.
무엇이든 타입도 마찬가지다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant